diff options
Diffstat (limited to 'usr/src/uts/common')
23 files changed, 22 insertions, 20909 deletions
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index da42d5e51d..af1f0d5137 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -1273,14 +1273,6 @@ PCWL_OBJS += pcwl.o PSET_OBJS += pset.o -PCI_I2ONEXUS_OBJS += pci_to_i2o.o - -I2OMSG_OBJS += i2o_msg.o - -I2O_SCSI_OBJS += i2o_scsi.o - -I2O_BS_OBJS += i2o_bs.o label.o - OHCI_OBJS += ohci.o ohci_hub.o ohci_polled.o UHCI_OBJS += uhci.o uhciutil.o uhcitgt.o uhcihub.o uhcipolled.o diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules index 76abd6c846..7b732ca525 100644 --- a/usr/src/uts/common/Makefile.rules +++ b/usr/src/uts/common/Makefile.rules @@ -495,10 +495,6 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/io/hotplug/pcihp/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) -$(OBJS_DIR)/%.o: $(UTSBASE)/common/io/i2o/%.c - $(COMPILE.c) -o $@ $< - $(CTFCONVERT_O) - $(OBJS_DIR)/%.o: $(UTSBASE)/common/io/ib/clients/rds/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) @@ -1291,9 +1287,6 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/hotplug/pcishpc/%.c $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/hotplug/pcihp/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL)) -$(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/i2o/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/ib/clients/rds/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL)) diff --git a/usr/src/uts/common/io/i2o/i2o_bs.c b/usr/src/uts/common/io/i2o/i2o_bs.c deleted file mode 100644 index dc6876a3c1..0000000000 --- a/usr/src/uts/common/io/i2o/i2o_bs.c +++ /dev/null @@ -1,3989 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/errno.h> -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/user.h> -#include <sys/buf.h> -#include <sys/ioctl.h> -#include <sys/file.h> -#include <sys/uio.h> -#include <sys/kmem.h> -#include <sys/cmn_err.h> -#include <sys/debug.h> -#include <sys/stat.h> -#include <sys/sysmacros.h> - - -#include <sys/hdio.h> -#include <sys/dkio.h> -#include <sys/cdio.h> -#include <sys/dktp/dadkio.h> - -#include <sys/dklabel.h> - -#include <sys/vtoc.h> - - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/dditypes.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> - - -/* BSA specific header files */ - -#include <sys/i2o/i2omstr.h> -#include <sys/i2o/i2omsg.h> -#include <sys/i2o/i2outil.h> -#include <sys/dktp/fdisk.h> -#include <sys/dktp/altsctr.h> -#include "i2o_bs.h" - - -char _depends_on[] = "misc/i2o_msg"; - -static int bsa_read(dev_t, struct uio *, cred_t *); -static int bsa_write(dev_t, struct uio *, cred_t *); -static int bsa_strategy(register struct buf *); -static int bsa_attach(dev_info_t *, ddi_attach_cmd_t); -static int bsa_detach(dev_info_t *, ddi_detach_cmd_t); -static int bsa_open(dev_t *, int, int, cred_t *); -static int bsa_close(dev_t, int, int, cred_t *); -static int bsa_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); -static int bsa_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); -static int bsa_prop_op(dev_t, dev_info_t *, ddi_prop_op_t, - int, char *, caddr_t, int *); -static int bsa_print(dev_t, char *); -static int bsa_dump(dev_t, caddr_t, daddr_t, int); -static int create_minor_node(dev_info_t *, bsa_data_t *); -static int update_vtoc(struct bsa_data *, dev_t); -static int redo_vtoc(struct buf *, struct bsa_data *); - - -static int write_dskvtoc(struct bsa_data *, dev_t, dsk_label_t *, - struct vtoc *, struct cb_ops *); -static int translate_error(int, int, int); -static void bsa_reply(void *, ddi_acc_handle_t); -static int BsaPowerMgt(bsa_data_t *, int); -static int bsa_buf_setup(void **, dev_t, enum uio_seg, int); -static void cap_translation(uint64_t, int *, int *, int *); -static int bsa_setup(struct bsa_data *); -static int bsa_lbl_ioctl(dev_t, int, int, int); -static void geom_prep(struct dk_geom *, struct bsa_unit *); -static void BsaMediaUnlock_reply(void *, ddi_acc_handle_t); -static int BsaMediaUnlock(bsa_data_t *); -static void BsaMediaLock_reply(void *, ddi_acc_handle_t); -static int BsaMediaLock(bsa_data_t *); -static void BsaPowerMgt_reply(void *, ddi_acc_handle_t); -static int BsaPowerMgt(bsa_data_t *, int); -static void BsaMediaEject_reply(void *, ddi_acc_handle_t); -static int BsaMediaEject(bsa_data_t *); -static int UtilEventRegister(bsa_data_t *, int); -static void UtilEventRegister_reply(void *, ddi_acc_handle_t); -static void UtilAbort_reply(void *, ddi_acc_handle_t); -static int UtilAbort(bsa_data_t *, int, uint8_t, uint64_t); -static void UtilNOP(i2o_iop_handle_t, ddi_acc_handle_t, - i2o_common_message_t *, i2o_msg_handle_t); -static int UtilClaim_release(bsa_data_t *); -static void UtilClaim_release_reply(void *, ddi_acc_handle_t); -static int UtilClaim(bsa_data_t *); -static void UtilClaim_reply(void *, ddi_acc_handle_t); -static void UtilParamsGet_reply(void *, ddi_acc_handle_t); -static int UtilParamsGet(bsa_data_t *); -static int parse_lct(void *, size_t, bsa_data_t *, ddi_acc_handle_t); - - -extern int parse_fdisk_lbl(struct buf *, dsk_label_t *, struct cb_ops *, - struct dk_geom *, int); -extern void dsklbl_read_label(struct buf *, dsk_label_t *, struct cb_ops *, - struct dk_geom *, int type); -extern int dsklbl_wrvtoc(dsk_label_t *, struct vtoc *, struct buf *, - struct cb_ops *); -extern void dsklbl_ondsklabel_to_vtoc(dsk_label_t *, struct vtoc *); -extern void dsklbl_dgtoug(struct dk_geom *, struct dk_label *); -extern void dsklbl_ugtodg(struct dk_geom *, struct dk_label *); - -/* - * Debug flag definitions. - */ -#define I2O_DEBUG_DIO 0x0001 /* disk specific info */ -#define I2O_DEBUG_DINT 0x0002 /* initialization */ -#define I2O_DEBUG_DLBL 0x0004 /* labeling info */ -#define I2O_DEBUG_GEN 0x0008 /* general debugging info */ -#define I2O_DEBUG_BADBLK 0x0009 /* Bad Block Debug */ - -#ifdef BSA_DEBUG -int bsa_debug = I2O_DEBUG_DIO; - -#define DEBUGF(flag, args) \ - { if (bsa_debug & (flag)) cmn_err args; } -#else -#define DEBUGF(level, args) /* nothing */ -#endif - -struct cb_ops bsa_cb_ops = { - bsa_open, /* driver open routine */ - bsa_close, /* driver close routine */ - bsa_strategy, /* driver strategy routine */ - bsa_print, /* driver print routine */ - bsa_dump, /* driver dump routine */ - bsa_read, /* driver read routine */ - bsa_write, /* driver write routine */ - bsa_ioctl, /* driver ioctl routine */ - nodev, /* driver devmap routine */ - nodev, /* driver mmap routine */ - nodev, /* driver segmap routine */ - nochpoll, /* driver chpoll routine */ - bsa_prop_op, /* driver prop_op routine */ - 0, /* driver cb_str - STREAMS only */ - D_64BIT|D_NEW | D_MTSAFE, /* driver compatibility flag */ - }; - -static struct dev_ops bsa_ops = { - DEVO_REV, /* devo_rev, */ - 0, /* refcnt */ - bsa_getinfo, /* info */ - nulldev, /* identify */ - nulldev, /* probe */ - bsa_attach, /* attach */ - bsa_detach, /* detach */ - nulldev, /* reset */ - &bsa_cb_ops, /* driver operations */ - 0, - }; - -char *i2o_bsa_name = I2O_BSA_NAME; /* Global not local */ -static void *bsa_soft = NULL; - -/* - * The following is used for buffers allocated by ddi_dma_mem_alloc() - */ - - -/* - * Several bugs in dma the -1 can not be used for sgllen since it is - * defined as short and the count_max and addr_hi because of the bug - * in the nexus can not be set to FFFFFFF. It will over flow. - */ - -static ddi_dma_attr_t dma_attr = { - DMA_ATTR_V0, /* dma_attr version */ - 0, /* dma_attr_addr_lo */ - (uint64_t)0xFFFFFFFe, /* dma_attr_addr_hi 64 bit address */ - (uint64_t)0xFFFFFFFe, /* dma_attr_count_max */ - 1, /* dma_attr_align. We do not care */ - 1, /* dma_attr_burstsizes.We do not care */ - 1, /* dma_attr_minxfer */ - (uint64_t)0xFFFFFFFF, /* dma_attr_maxxfer 64 bit address */ - (uint64_t)0xFFFFFFFF, /* dma_attr_seg 64 bit */ - 0xFFF, /* dma_attr_sgllen. No limit in I2O */ - 1, /* dma_attr_granular */ - 0, /* dma_attr_flags */ -}; - - -/* - * For SGL gain, we need one contiguous buffer - */ -static ddi_dma_attr_t dma_attr_sglfrm = { - DMA_ATTR_V0, /* dma_attr version */ - 0, /* dma_attr_addr_lo */ - (uint64_t)0xFFFFFFFe, /* dma_attr_addr_hi */ - (uint64_t)0xFFFFFFFe, /* dma_attr_count_max. */ - 1, /* dma_attr_align */ - 1, /* dma_attr_burstsizes */ - 1, /* dma_attr_minxfer */ - (uint64_t)0xFFFFFFFF, /* dma_attr_maxxfer */ - (uint64_t)0xFFFFFFFF, /* dma_attr_seg */ - 1, /* dma_attr_sgllen */ - 1, /* dma_attr_granular */ - 0, /* dma_attr_flags */ -}; - -/* - * For LCT table. We need one contiguous buffer - */ -static ddi_dma_attr_t dma_attr_lcttbl = { - DMA_ATTR_V0, /* dma_attr version */ - 0, /* dma_attr_addr_lo */ - (uint64_t)0xFFFFFFFe, /* dma_attr_addr_hi */ - (uint64_t)0xFFFFFFFe, /* dma_attr_count_max. 24 bit */ - 1, /* dma_attr_align */ - 1, /* dma_attr_burstsizes */ - 1, /* dma_attr_minxfer */ - (uint64_t)0xFFFFFFFF, /* dma_attr_maxxfer */ - (uint64_t)0xFFFFFFFF, /* dma_attr_seg */ - 1, /* dma_attr_sgllen */ - 1, /* dma_attr_granular */ - 0, /* dma_attr_flags */ -}; - - -/* DMA access attributes */ -static ddi_device_acc_attr_t accattr = { - DDI_DEVICE_ATTR_V0, - DDI_STRUCTURE_LE_ACC, - DDI_STRICTORDER_ACC, -}; - -#include <sys/modctl.h> - -extern struct mod_ops mod_driverops; - -static struct modldrv modldrv = { - &mod_driverops, /* Type of module. This one is a driver */ - "I2O Block Storage OSM %I%", - &bsa_ops, /* driver ops */ -}; - -static struct modlinkage modlinkage = { - MODREV_1, (void *)&modldrv, NULL -}; - -/* - * Set up the message - * - set up the Standard Message frame fields: - * MsgFlags, InitiatorContext, Function, msgsize and TID - * MsgFlags need to be 0x2 in case of 64 bit - */ - -#define setup_msghdr(func, replyfunc, mp, acc_hdl, veroff, tid, \ - msgflags, msgsize) \ - { \ - put_msg_Function((mp), (func), acc_hdl); \ - (mp)->VersionOffset = (veroff); \ - (mp)->MsgFlags = (msgflags); \ - ddi_put16(acc_handle, \ - &(mp)->MessageSize, (msgsize) >> 2); \ - put_msg_InitiatorAddress((mp), I2O_HOST_TID, \ - acc_hdl); \ - put_msg_TargetAddress((mp), tid, acc_hdl); \ - ddi_put32(acc_hdl, (uint32_t *)&(mp)->InitiatorContext. \ - initiator_context_32bits, (uint32_t)replyfunc); \ - } - -int -_init(void) -{ - int status; - - if (status = mod_install(&modlinkage)) - return (status); - - status = ddi_soft_state_init(&bsa_soft, sizeof (struct bsa_data), 1); - - return (status); -} - - -int -_fini(void) -{ - int status; - - status = mod_remove(&modlinkage); - if (!status) - ddi_soft_state_fini(&bsa_soft); - - return (status); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - -/* - * The Block storage strategy routine - */ - -int -bsa_strategy(struct buf *bp) -{ - struct bsa_unit *bsa_unit; - struct bsa_data *bsadata; - struct bsa_context *tcontextp = NULL; - int instance; - daddr_t blkno; - unsigned long absblkno; - - i2o_msg_handle_t msg_handle; - ddi_acc_handle_t acc_handle; - ddi_acc_handle_t sgl_acchdl; - uint_t nocookies; - uint_t sgncookies; - ddi_dma_cookie_t dma_cookie; - ddi_dma_cookie_t dma_sgcookie; - int bind = 0; - int sgbind = 0; - int flags; - i2o_sge_simple_element_t *sglbuf = NULL; - i2o_sge_simple_element_t *sgl = NULL; - i2o_bsa_write_message_t *msgbuf = NULL; - int sgsize; - int numsgl; - size_t real_length; - ssize_t resid = 0; - int ret = 0; - int part; - long secnt, count; - -#ifdef lint - sgl_acchdl = NULL; - acc_handle = sgl_acchdl; -#endif - /* - * get instance number - */ - instance = UNIT(bp->b_edev); - - if (!(bsadata = ddi_get_soft_state(bsa_soft, instance))) { - ret = ENXIO; - goto out; - } - - if (bp->b_bcount & (NBPSCTR-1)) { - ret = ENXIO; - goto out; - } - - - bsa_unit = &bsadata->unitp; - - DEBUGF(I2O_DEBUG_DIO, (CE_CONT, "?bsa_strategy:cyl = %d acyl = %d" - " head = %d" "sec = %d\n", - bsadata->unitp.au_cyl, - bsadata->unitp.au_acyl, - bsadata->unitp.au_hd, - bsadata->unitp.au_sec)); - - DEBUGF(I2O_DEBUG_DIO, (CE_CONT, "?bsa_strategy:bp->b_private = %d" - "\n", bp->b_private)); - - /* - * Reject CD write commands. - */ - - if ((bsadata->unitp.au_type == DKC_CDROM) && !(bp->b_flags & B_READ)) { - ret = EIO; - goto out; - } - - if ((bp->b_flags & B_PAGEIO) || (bp->b_flags & B_PHYS)) - bp_mapin(bp); - - bp->b_resid = 0; - - DEBUGF(I2O_DEBUG_GEN, (CE_CONT, "?bsa_strategy: %s request for buf:" - "%x\n", bp->b_flags & B_READ ? "read" : "write", bp)); - - blkno = dkblock(bp); - - part = LPART(bp->b_edev); - - /* - * Map block number within partition to absolute - * block number. - */ - - DEBUGF(I2O_DEBUG_DIO, (CE_CONT, "?BS d%d%c%d: " - "%s block %d mapped to %ld dev %lx\n", - instance, (part > 15 ? 'p' : 's'), - (part > 15 ? part - 16 : part), - bp->b_flags & B_READ ? "read" : "write", blkno, - blkno + bsadata->lbl.pmap[part].p_start, - bp->b_edev)); - DEBUGF(I2O_DEBUG_DIO, (CE_CONT, "? p_size = <%ld> <0x%lx>\n", - bsadata->lbl.pmap[part].p_size, - bsadata->lbl.pmap[part].p_size)); - - if (bsadata->lbl.pmap[part].p_flag & V_INVALID) { - ret = ENXIO; - - DEBUGF(I2O_DEBUG_DLBL, (CE_CONT, "?bs_strategy:" - "invalid slice bp 0x%x\n", bp)); - goto out; - } - - - /* - * Make sure we don't run off the end of a partition. - */ - if ((bsadata->lbl.vtocread == 1) && (bp->b_private != (void *)0xBEE)) { - secnt = (bp->b_bcount + (DEV_BSIZE - 1)) >> DEV_BSHIFT; - count = MIN(secnt, (bsadata->lbl.pmap[part].p_size - blkno)); - - DEBUGF(I2O_DEBUG_DLBL, (CE_CONT, "?bs_strategy:" - "secnt = %d count = %d part = %d b_bcount =%d\n", - secnt, count, part, bp->b_bcount)); - - if (count != secnt) { - if (count >= 0) { - resid = (secnt - count) << DEV_BSHIFT; - cmn_err(CE_CONT, "overrun by %ld sectors\n", - secnt - count); - bp->b_bcount -= resid; - } else { - DEBUGF(I2O_DEBUG_DLBL, (CE_CONT, - "I/O attempted beyond the end of partition")); - ret = ENXIO; - goto out; - } - } - } - absblkno = bsadata->lbl.pmap[part].p_start + blkno; - - /* - * Allocate transaction context - */ - - tcontextp = (struct bsa_context *)kmem_zalloc(sizeof (bsa_context_t), - KM_SLEEP); - tcontextp->bsadata = bsadata; - - - bind = 0; - sgbind = 0; - - if (ddi_dma_alloc_handle(bsadata->dip, &dma_attr, DDI_DMA_SLEEP, 0, - &tcontextp->dma_handle) != DDI_SUCCESS) { - cmn_err(CE_CONT, "?BS_strategy: No resources available\n"); - ret = ENOMEM; - goto out; - } - - flags = (bp->b_flags & B_READ) ? DDI_DMA_READ | DDI_DMA_STREAMING: - DDI_DMA_WRITE | DDI_DMA_STREAMING; - - ret = ddi_dma_buf_bind_handle(tcontextp->dma_handle, bp, - flags, DDI_DMA_SLEEP, 0, &dma_cookie, &nocookies); - - switch (ret) { - case DDI_DMA_MAPPED: - /* - * This flag used in case of error to unbind the DMA handle - * The address is bound to DMA handle - */ - bind = 1; - break; - - case DDI_DMA_NORESOURCES: - ret = ENOMEM; - cmn_err(CE_CONT, "?bsa_strategy: No DMA resources available\n"); - goto out; - - case DDI_DMA_INUSE: - case DDI_DMA_TOOBIG: - ret = EINVAL; - goto out; - - case DDI_DMA_NOMAPPING: - default: - ret = EFAULT; - cmn_err(CE_CONT, "?bsa_strategy: DMA failed 0x%x\n", ret); - goto out; - } - - /* - * Allocate a message frame from IOP's inbound queue - * Sleep until the resource is available - */ - - if (i2o_msg_alloc(bsadata->iop, I2O_MSG_SLEEP, NULL, (void **)&msgbuf, - &msg_handle, &acc_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?bsa_strategy: Frame buffer " - "resource not available\n"); - ret = ENOMEM; - goto out; - } - - /* - * Note that the MessageSize is multiples of 4 byte, hence the shift - */ - - sgsize = ((ddi_get16(acc_handle, - &msgbuf->StdMessageFrame.MessageSize)) << 2) - - (sizeof (i2o_message_frame_t) + - sizeof (i2o_transaction_context_t) + - sizeof (i2o_bsa_read_flags_t) + - (2 * (sizeof (uint8_t)))+ - sizeof (uint32_t) + - sizeof (uint64_t)); - - /* - * If we can not fit all the SGL elements in the Frame we need to - * create a SGL chain which will contain all the SGL elements. - */ - if (nocookies <= (sgsize/sizeof (i2o_sge_simple_element_t))) { - /* we can place the SGL within the MSG frame */ - sgl = &msgbuf->SGL.u1.Simple[0]; - sgl_acchdl = acc_handle; - numsgl = nocookies; - } else { - i2o_sge_chain_element_t *sgl_chainp = NULL; - - /* - * allocate buffer to hold the SGL list. - * I2O only accepts one SGL chain buf. So we - * need one contigous segment. (1 cookie). - */ - - if ((ddi_dma_alloc_handle(tcontextp->bsadata->dip, - &dma_attr_sglfrm, - DDI_DMA_SLEEP, 0, &tcontextp->dma_sghandle)) - != DDI_SUCCESS) { - ret = ENOMEM; - cmn_err(CE_CONT, "?bsa_strategy: No resources " - "available\n"); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - - } - - if ((ddi_dma_mem_alloc(tcontextp->dma_sghandle, - (size_t)(nocookies * sizeof (i2o_sge_simple_element_t)), - &accattr, DDI_DMA_STREAMING, DDI_DMA_SLEEP, 0, - (caddr_t *)&sglbuf, &real_length, - &tcontextp->acc_sghandle)) != DDI_SUCCESS) { - - ret = ENOMEM; - cmn_err(CE_CONT, "?bsa_strategy: No resources " - "available\n"); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - } - - - ret = ddi_dma_addr_bind_handle(tcontextp->dma_sghandle, NULL, - (caddr_t)sglbuf, real_length, - DDI_DMA_READ | DDI_DMA_STREAMING, DDI_DMA_SLEEP, 0, - &dma_sgcookie, &sgncookies); - - /* - * This flag used in case of error to unbind - */ - - switch (ret) { - case DDI_DMA_MAPPED: - /* - * This flag used in case of error to unbind the DMA - * handle The address is bound to DMA handle - */ - sgbind = 1; - break; - case DDI_DMA_NORESOURCES: - ret = ENOMEM; - cmn_err(CE_CONT, "?bsa_strategy:" - " No DMA resources available\n"); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - - case DDI_DMA_INUSE: - case DDI_DMA_TOOBIG: - ret = ENOMEM; - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - - case DDI_DMA_NOMAPPING: - default: - ret = EFAULT; - cmn_err(CE_CONT, "?bsa_strategy:" - " DMA failed 0x%x\n", ret); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - - goto out; - } - - /* - * In the MSG frame initialize the chain element and - * followed by sgl_ignore element (this seems necessary?) - */ - sgl_chainp = &msgbuf->SGL.u1.Chain; - - put_flags_count_Count(&sgl_chainp[0].FlagsCount, - real_length, acc_handle); - - - put_flags_count_Flags(&sgl_chainp[0].FlagsCount, - I2O_SGL_FLAGS_CHAIN_POINTER_ELEMENT, acc_handle); - - ddi_put32(acc_handle, &sgl_chainp[0].PhysicalAddress, - (uint32_t)dma_sgcookie.dmac_address); - - - put_flags_count_Count(&sgl_chainp[1].FlagsCount, - real_length, acc_handle); - - - put_flags_count_Flags(&sgl_chainp[1].FlagsCount, - I2O_SGL_FLAGS_IGNORE_ELEMENT | I2O_SGL_FLAGS_LAST_ELEMENT, - acc_handle); - - /* set the SGL list pointer to the allocated buffer */ - sgl = (i2o_sge_simple_element_t *)sglbuf; - sgl_acchdl = tcontextp->acc_sghandle; - numsgl = 2; - } - - /* - * copy the cookies to the SGL list. - */ - - while (nocookies) { - put_flags_count_Count(&sgl->FlagsCount, dma_cookie.dmac_size, - sgl_acchdl); - put_flags_count_Flags(&sgl->FlagsCount, - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT, sgl_acchdl); - ddi_put32(acc_handle, &sgl->PhysicalAddress, - dma_cookie.dmac_address); - - if (!(--nocookies)) { - put_flags_count_Flags(&sgl->FlagsCount, - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT | - I2O_SGL_FLAGS_LAST_ELEMENT | - I2O_SGL_FLAGS_END_OF_BUFFER, sgl_acchdl); - break; - } - - ddi_dma_nextcookie(tcontextp->dma_handle, &dma_cookie); - sgl++; - } - - - /* - * Set up the Standard Message frame fields - */ - - setup_msghdr((bp->b_flags & B_READ ? I2O_BSA_BLOCK_READ : - I2O_BSA_BLOCK_WRITE), bsa_reply, &msgbuf->StdMessageFrame, - acc_handle, 0x81, bsadata->tid, 0, - sizeof (i2o_bsa_write_message_t) + - (numsgl * sizeof (i2o_sge_simple_element_t)) - - sizeof (i2o_sg_element_t)); - - - ddi_put32(acc_handle, &msgbuf->TransferByteCount, bp->b_bcount); - ddi_put64(acc_handle, &msgbuf->LogicalByteAddress, - (((uint64_t)(absblkno)) * bsa_unit->au_blksize)); - - ddi_put16(acc_handle, &msgbuf->ControlFlags, 0); - ddi_put8(acc_handle, &msgbuf->TimeMultiplier, 1); - - /* - * Set the Transaction Context field (used for reply correlation) - */ - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContext, - (uint32_t)tcontextp); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContext, - (uint32_t)(uintptr_t)tcontextp); -#endif - - if (i2o_msg_send(bsadata->iop, msgbuf, msg_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?bsa_strategy: i2o_msg_send failed"); - ret = ENOMEM; - goto out; - } - - /* - * Wait until the reply is done - * do a cv_wait here from reply - */ - mutex_enter(&bsadata->bsa_mutex); - while (!(tcontextp->rwreplyflag & REPLY_DONE)) - cv_wait(&bsadata->rwreply_cv, &bsadata->bsa_mutex); - mutex_exit(&bsadata->bsa_mutex); - - if ((ret = tcontextp->retval) != 0) { - cmn_err(CE_CONT, "? bsa_strategy:Error %d. Operation on " - "block %ld failed. det Error 0x%x." - "\n", ret, absblkno, tcontextp->deterror); - DEBUGF(I2O_DEBUG_BADBLK, (CE_CONT, "?bsa_strategy:Error %d." - "Operation on block <%d> maped to %ld failed." - "det Error %x.\n", ret, dkblock(bp), absblkno, - tcontextp->deterror)); - - DEBUGF(I2O_DEBUG_BADBLK, (CE_CONT, "?BS d%d%c%d: " - "%s block %d mapped to %ld dev %lx\n", - instance, (part > 15 ? 'p' : 's'), - (part > 15 ? part - 16 : part), - bp->b_flags & B_READ ? "read" : "write", dkblock(bp), - dkblock(bp) + bsadata->lbl.pmap[part].p_start, - bp->b_edev)); - DEBUGF(I2O_DEBUG_BADBLK, (CE_CONT, "? p_size = <%ld> <0x%lx>\n", - bsadata->lbl.pmap[part].p_size, - bsadata->lbl.pmap[part].p_size)); - - goto out; - } - - /* - * free up the resources (unbind, free buff, free handle). - */ - if (sgbind) - (void) ddi_dma_unbind_handle(tcontextp->dma_sghandle); - if (sglbuf) - ddi_dma_mem_free(&tcontextp->acc_sghandle); - if (tcontextp) - if (tcontextp->dma_sghandle) - ddi_dma_free_handle(&tcontextp->dma_sghandle); - if (bind) - (void) ddi_dma_unbind_handle(tcontextp->dma_handle); - if (tcontextp) - if (tcontextp->dma_handle) - ddi_dma_free_handle(&tcontextp->dma_handle); - if (tcontextp) - kmem_free(tcontextp, sizeof (bsa_context_t)); - - - /* - * In Intel land if the disk block to be written to is disk block 0, - * it would mean the partition table is changing from underneath us - * we shoud trap and update the in memory image. - * By now the buffer is mapped in and we should be able to - * use the contents as the new fdisk partition. - */ -#if defined(_SUNOS_VTOC_16) - if (!(bp->b_flags & B_READ) && - ((bp->b_flags & B_ERROR) != B_ERROR) && absblkno == 0) { - (void) redo_vtoc(bp, bsadata); - } -#endif - biodone(bp); - return (0); - -out: - /* return FAILURE */ - - if (sgbind) - (void) ddi_dma_unbind_handle(tcontextp->dma_sghandle); - if (sglbuf) - ddi_dma_mem_free(&tcontextp->acc_sghandle); - if (tcontextp) - if (tcontextp->dma_sghandle) - ddi_dma_free_handle(&tcontextp->dma_sghandle); - if (bind) - (void) ddi_dma_unbind_handle(tcontextp->dma_handle); - if (tcontextp) - if (tcontextp->dma_handle) - ddi_dma_free_handle(&tcontextp->dma_handle); - if (tcontextp) - kmem_free(tcontextp, sizeof (bsa_context_t)); - - - bp->b_resid = bp->b_bcount; - bioerror(bp, ret); - biodone(bp); - return (0); -} - -/* - * Redo the vtoc. This is done whenever the vtoc is changes under us. - */ - -static int -redo_vtoc(struct buf *fdiskbp, struct bsa_data *bsadata) -{ - struct dk_geom dkg; - struct buf *bp; - int status; - dev_t dev; - char *secbuf; - - - dev = makedevice(getmajor(fdiskbp->b_edev), - BSA_SETMINOR(bsadata->instance, FDISK_OFFSET)); - - DEBUGF(I2O_DEBUG_DLBL, (CE_CONT, "?redo_vtoc: dev = %x\n", dev)); - /* - * Allocate a temporary block for labeling use. - */ - - secbuf = kmem_zalloc(NBPSCTR, KM_SLEEP); - - bp = getrbuf(KM_SLEEP); - - bp->b_edev = dev; - bp->b_dev = cmpdev(dev); - bp->b_flags = B_BUSY; - bp->b_resid = 0; - bp->b_bcount = NBPSCTR; - bp->b_un.b_addr = (caddr_t)secbuf; - - DEBUGF(I2O_DEBUG_DLBL, (CE_CONT, "?redo_vtoc" - "edev = %x dev = %x\n", bp->b_edev, bp->b_dev)); - - bcopy(fdiskbp->b_un.b_addr, bp->b_un.b_addr, NBPSCTR); - - geom_prep(&dkg, &bsadata->unitp); - - status = parse_fdisk_lbl(bp, &bsadata->lbl, - &bsa_cb_ops, &dkg, bsadata->unitp.au_type); - - /* - * Free the temporary block allocated for labeling purposes - */ - kmem_free(bp->b_un.b_addr, NBPSCTR); - freerbuf(bp); - - - if (status == DDI_FAILURE) - return (EFAULT); - else - return (0); -} - -/* - * Update the vtoc - */ - -static int -update_vtoc(struct bsa_data *bsadata, dev_t dev) -{ - struct dk_geom dkg; - struct buf *bp; - dev_t newdev; - char *secbuf; - - /* - * Get a dev with specific minor number - */ - - newdev = makedevice(getmajor(dev), - BSA_SETMINOR(bsadata->instance, FDISK_OFFSET)); - - DEBUGF(I2O_DEBUG_DLBL, (CE_CONT, "?update_vtoc newdev = %x\n", newdev)); - /* - * Allocate a temporary block for labeling use. - */ - - secbuf = kmem_zalloc(NBPSCTR, KM_SLEEP); - - bp = getrbuf(KM_SLEEP); - - bp->b_edev = newdev; - bp->b_dev = cmpdev(newdev); - bp->b_flags = B_BUSY; - bp->b_resid = 0; - bp->b_bcount = NBPSCTR; - bp->b_un.b_addr = (caddr_t)secbuf; - - DEBUGF(I2O_DEBUG_DLBL, (CE_CONT, "?update_vtoc:" - "edev = %x newdev = %x\n", bp->b_edev, bp->b_dev)); - - geom_prep(&dkg, &bsadata->unitp); - dsklbl_read_label(bp, &bsadata->lbl, &bsa_cb_ops, &dkg, - bsadata->unitp.au_type); - - /* - * Free the temporary block allocated for labeling purposes - */ - kmem_free(bp->b_un.b_addr, NBPSCTR); - freerbuf(bp); - - return (0); -} - - -/* - * Write the Vtoc - */ - - -static int -write_dskvtoc(struct bsa_data *bsadata, dev_t dev, dsk_label_t *lblp, - struct vtoc *vtocp, struct cb_ops *dev_ops) -{ - struct buf *bp; - int status; - char *secbuf; - - - dev = makedevice(getmajor(dev), - BSA_SETMINOR(bsadata->instance, FDISK_OFFSET)); - /* - * Allocate a temporary block for labeling use. - */ - secbuf = kmem_zalloc(NBPSCTR, KM_SLEEP); - - bp = getrbuf(KM_SLEEP); - - bp->b_edev = dev; - bp->b_dev = cmpdev(dev); - bp->b_flags = B_BUSY; - bp->b_resid = 0; - bp->b_bcount = NBPSCTR; - bp->b_un.b_addr = (caddr_t)secbuf; - - - DEBUGF(I2O_DEBUG_DLBL, (CE_CONT, "?write_dskvtoc:" - "edev = %x dev = %x\n", bp->b_edev, bp->b_dev)); - - status = dsklbl_wrvtoc(lblp, vtocp, bp, dev_ops); - - /* - * Free the temporary block allocated for labeling purposes - */ - kmem_free(bp->b_un.b_addr, NBPSCTR); - freerbuf(bp); - - return (status); -} - - -/* - * Reply call back function - */ - -static void -bsa_reply(void *msg, ddi_acc_handle_t acc_handle) -{ - - bsa_context_t *tcontextp; /* Context field */ - int detstatus; /* detailed status */ - int reqstatus; /* request status */ - - - /* - * Correlate replies with appropriate request, based on - * the content of the Transaction Context field. 3.4.1.2.1 - * Used context structure in strategy routine. Which bp is part - * of it. - */ - - /* - * Get the Transacton Context field - */ - -#if I2O_64BIT_CONTEXT - tcontextp = (bsa_context_t *)ddi_get64(acc_handle, - &(((i2o_single_reply_message_frame_t *)msg)->TransactionContext)); -#else - tcontextp = (bsa_context_t *)(uintptr_t)ddi_get32(acc_handle, - &(((i2o_single_reply_message_frame_t *)msg)->TransactionContext)); -#endif - - /* - * Detailed status - */ - - detstatus = ddi_get16(acc_handle, - &((i2o_single_reply_message_frame_t *)msg)->DetailedStatusCode); - - /* - * reply status - */ - reqstatus = ((i2o_single_reply_message_frame_t *)msg)->ReqStatus; - - tcontextp->retval = translate_error(reqstatus, detstatus, 0); - tcontextp->deterror = detstatus; - - /* - * Let the strategy routine to continue - */ - - mutex_enter(&tcontextp->bsadata->bsa_mutex); - tcontextp->rwreplyflag |= REPLY_DONE; - cv_broadcast(&tcontextp->bsadata->rwreply_cv); - mutex_exit(&tcontextp->bsadata->bsa_mutex); -} - -/* - * Translate the error - */ - - -#ifdef BSA_DEBUG -struct err_map { - int errorval; - char *errstr; -}; - -static struct err_map i2o_errtab[] = { - { I2O_REPLY_STATUS_SUCCESS, - "SUCCESS" }, - { I2O_REPLY_STATUS_ABORT_DIRTY, - "ABORT_DIRTY" }, - { I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER, - "ABORT_NO_DATA_TRANSFER" }, - { I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER, - "ABORT_PARTIAL_TRANSFER" }, - { I2O_REPLY_STATUS_ERROR_DIRTY, - "ERROR_DIRTY" }, - { I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER, - "ERROR_NO_DATA_TRANSFER" }, - { I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER, - "ERROR_PARTIAL_TRANSFER" }, - { I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY, - "PROCESS_ABORT_DIRTY" }, - { I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER, - "PROCESS_ABORT_NO_DATA_TRANSFER" }, - { I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER, - "PROCESS_ABORT_PARTIAL_TRANSFER" }, - { I2O_REPLY_STATUS_TRANSACTION_ERROR, - "TRANSACTION_ERROR" }, - { I2O_REPLY_STATUS_PROGRESS_REPORT, - "PROGRESS_REPORT" }, -}; - - - -static struct err_map util_errtab[] = { - { I2O_DETAIL_STATUS_SUCCESS, - "SUCCESS" }, - { I2O_DETAIL_STATUS_BAD_KEY, - "BAD_KEY" }, - { I2O_DETAIL_STATUS_TCL_ERROR, - "TCL_ERROR" }, - { I2O_DETAIL_STATUS_REPLY_BUFFER_FULL, - "REPLY_BUFFER_FULL" }, - { I2O_DETAIL_STATUS_NO_SUCH_PAGE, - "NO_SUCH_PAGE" }, - { I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_SOFT, - "INSUFFICIENT_RESOURCE_SOFT" }, - { I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_HARD, - "INSUFFICIENT_RESOURCE_HARD" }, - { I2O_DETAIL_STATUS_CHAIN_BUFFER_TOO_LARGE, - "CHAIN_BUFFER_TOO_LARGE" }, - { I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION, - "UNSUPPORTED_FUNCTION" }, - { I2O_DETAIL_STATUS_DEVICE_LOCKED, - "DEVICE_LOCKED" }, - { I2O_DETAIL_STATUS_DEVICE_RESET, - "DEVICE_RESET" }, - { I2O_DETAIL_STATUS_INAPPROPRIATE_FUNCTION, - "INAPPROPRIATE_FUNCTION" }, - { I2O_DETAIL_STATUS_INVALID_INITIATOR_ADDRESS, - "INVALID_INITIATOR_ADDRESS" }, - { I2O_DETAIL_STATUS_INVALID_MESSAGE_FLAGS, - "INVALID_MESSAGE_FLAGS" }, - { I2O_DETAIL_STATUS_INVALID_OFFSET, - "INVALID_OFFSET" }, - { I2O_DETAIL_STATUS_INVALID_PARAMETER, - "INVALID_PARAMETER" }, - { I2O_DETAIL_STATUS_INVALID_REQUEST, - "INVALID_REQUEST" }, - { I2O_DETAIL_STATUS_INVALID_TARGET_ADDRESS, - "INVALID_TARGET_ADDRESS" }, - { I2O_DETAIL_STATUS_MESSAGE_TOO_LARGE, - "MESSAGE_TOO_LARGE" }, - { I2O_DETAIL_STATUS_MESSAGE_TOO_SMALL, - "MESSAGE_TOO_SMALL" }, - { I2O_DETAIL_STATUS_MISSING_PARAMETER, - "MISSING_PARAMETER" }, - { I2O_DETAIL_STATUS_TIMEOUT, - "TIMEOUT" }, - { I2O_DETAIL_STATUS_UNKNOWN_ERROR, - "UNKNOWN_ERROR" }, - { I2O_DETAIL_STATUS_UNKNOWN_FUNCTION, - "UNKNOWN_FUNCTION" }, - { I2O_DETAIL_STATUS_UNSUPPORTED_VERSION, - "UNSUPPORTED_VERSION" }, - { I2O_DEATIL_STATUS_DEVICE_BUSY, - "DEVICE_BUSY" }, - { I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE, - "DEVICE_NOT_AVAILABLE" }, -}; - -static struct err_map bsa_errtab[] = { - { I2O_BSA_DSC_SUCCESS, - "SUCCESS" }, - { I2O_BSA_DSC_MEDIA_ERROR, - "MEDIA_ERROR" }, - { I2O_BSA_DSC_ACCESS_ERROR, - "ACCESS_ERROR" }, - { I2O_BSA_DSC_DEVICE_FAILURE, - "DEVICE_FAILURE" }, - { I2O_BSA_DSC_DEVICE_NOT_READY, - "DEVICE_NOT_READY" }, - { I2O_BSA_DSC_MEDIA_NOT_PRESENT, - "MEDIA_NOT_PRESENT" }, - { I2O_BSA_DSC_MEDIA_LOCKED, - "MEDIA_LOCKED" }, - { I2O_BSA_DSC_MEDIA_FAILURE, - "MEDIA_FAILURE" }, - { I2O_BSA_DSC_PROTOCOL_FAILURE, - "PROTOCOL_FAILURE" }, - { I2O_BSA_DSC_BUS_FAILURE, - "BUS_FAILURE" }, - { I2O_BSA_DSC_ACCESS_VIOLATION, - "ACCESS_VIOLATION" }, - { I2O_BSA_DSC_WRITE_PROTECTED, - "WRITE_PROTECTED" }, - { I2O_BSA_DSC_DEVICE_RESET, - "DEVICE_RESET" }, - { I2O_BSA_DSC_VOLUME_CHANGED, - "VOLUME_CHANGED" }, - { I2O_BSA_DSC_TIMEOUT, - "TIMEOUT" }, -}; - -#endif - -/* - * Translate the error - */ - -/*ARGSUSED*/ -static int -translate_error(int reqstatus, int detstatus, int utilflag) -{ -#ifdef BSA_DEBUG - char *bsastr = "Unknown reason"; - char *i2ostr = "Unknown reason"; - char *utilstr = "Unknown reason"; - int i; -#endif - - if (reqstatus == I2O_REPLY_STATUS_SUCCESS && - detstatus == I2O_BSA_DSC_SUCCESS) - return (0); - -#ifdef BSA_DEBUG - - for (i = 0; i < sizeof (i2o_errtab)/sizeof (struct err_map); i++) { - if (i2o_errtab[i].errorval == reqstatus) { - i2ostr = i2o_errtab[i].errstr; - break; - } - } - - /* - * Util functions Detailed error - */ - - if (utilflag) { - for (i = 0; i < sizeof (util_errtab)/sizeof (struct err_map); - i++) { - if (util_errtab[i].errorval == detstatus) { - utilstr = util_errtab[i].errstr; - break; - } - } - } else { - - for (i = 0; i < sizeof (bsa_errtab)/sizeof (struct err_map); - i++) { - if (bsa_errtab[i].errorval == detstatus) { - bsastr = bsa_errtab[i].errstr; - break; - } - } - } - - DEBUGF(I2O_DEBUG_GEN, (CE_CONT, "?i2o_bs: %s. Error code = 0x%x\n", - i2ostr, reqstatus)); - - - if (utilflag) { - DEBUGF(I2O_DEBUG_GEN, (CE_CONT, "?I2o_bs: %s. Error code = 0x%x" - " \n", utilstr, detstatus)); - } else { - DEBUGF(I2O_DEBUG_GEN, (CE_CONT, "?I2o_bs: %s. Error code = 0x%x" - " \n", bsastr, detstatus)); - } -#endif - return (EIO); -} - - -/* - * attach routine for Block Stroage - */ - - -static int -bsa_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) -{ - - i2o_iop_handle_t handle = NULL; /* IOP handle to be initialized. */ - uint_t tid; /* Target id of I2O device */ - caddr_t *buf = NULL; /* Buffer that keeps the LCT table */ - size_t real_length; - int instance; - size_t buf_size = 0; - size_t lct_size; - size_t real_size; - int mask = 0; - major_t devmajor; - - ddi_acc_handle_t acc_handle = NULL; - ddi_dma_handle_t dma_handle = NULL; /* DMA Handle */ - - struct bsa_data *bsadata = NULL; - - /* - * resume from a checkpoint none of the DDM provided this so just ignor - */ - - if (cmd == DDI_RESUME) { - /* - * Power Up, load: power up the device completely and load - * medium, if present. We assume all the pointers are - * correct. Since we are resuming - */ - - instance = ddi_get_instance(dip); - bsadata = ddi_get_soft_state(bsa_soft, instance); - - if (BsaPowerMgt(bsadata, I2O_BSA_POWER_MGT_POWER_UP_LOAD)) - return (DDI_FAILURE); - - return (DDI_SUCCESS); - } - - if (cmd != DDI_ATTACH) { - DEBUGF(I2O_DEBUG_GEN, (CE_CONT, "?bs_attach:" - "returning FAILURE\n")); - return (DDI_FAILURE); - } - - /* - * register the OSM with the IOP - */ - - if (i2o_msg_osm_register(dip, &handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "BSA OSM's registeration failed\n"); - return (DDI_FAILURE); - } - - /* - * Get the size of LCT - */ - - if (i2o_msg_get_lct(handle, NULL, buf_size, &lct_size, &real_size) == - DDI_FAILURE) { - cmn_err(CE_CONT, "Could not acquire the configuration table\n"); - goto out; - } - - /* - * allocate buffer for LCT table - */ - - if (ddi_dma_alloc_handle(dip, &dma_attr_lcttbl, - DDI_DMA_SLEEP, 0, &dma_handle) != DDI_SUCCESS) { - cmn_err(CE_CONT, "?bsa_attach: No resources available\n"); - goto out; - } - - - if (ddi_dma_mem_alloc(dma_handle, lct_size, - &accattr, DDI_DMA_STREAMING, DDI_DMA_SLEEP, 0, - (caddr_t *)&buf, &real_length, &acc_handle) - != DDI_SUCCESS) { - cmn_err(CE_CONT, "?bsa_attach: No resources available\n"); - goto out; - } - - /* - * Get a copy of LCT - */ - - if (i2o_msg_get_lct(handle, buf, lct_size, NULL, NULL) == - DDI_FAILURE) { - cmn_err(CE_CONT, "could not acquire the configuration table\n"); - goto out; - } - - - if ((tid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "i2o-device-id", -1)) == -1) { - - cmn_err(CE_CONT, "?bsa_attach: unable to get the Tid\n"); - goto out; - } - - /* - * Allocate soft state associated with this instance. - */ - instance = ddi_get_instance(dip); - if (ddi_soft_state_zalloc(bsa_soft, instance) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_GEN, (CE_CONT, "?bsa_attach:" - "Unable to alloc state\n")); - goto out; - } - - /* Initialize the conditional variable and the mutex */ - bsadata = ddi_get_soft_state(bsa_soft, instance); - bsadata->dip = dip; - bsadata->instance = instance; - bsadata->crashbuf = getrbuf(KM_SLEEP); - - bsadata->tid = tid; /* Target ID of the I2O dev */ - bsadata->iop = handle; /* IOP access handle */ - bsadata->open_flag = 0; /* open flag */ - - cv_init(&bsadata->reply_cv, NULL, CV_DRIVER, NULL); - cv_init(&bsadata->state_cv, NULL, CV_DRIVER, NULL); - mutex_init(&bsadata->bsa_mutex, NULL, MUTEX_DRIVER, NULL); - mutex_init(&bsadata->lbl.mutex, NULL, MUTEX_DRIVER, NULL); - - /* - * parse the lct table to find out if the device is free or not - */ - - if (parse_lct(buf, lct_size, bsadata, acc_handle)) { - goto out; - } - - ddi_report_dev(dip); /* announce the drive */ - - devmajor = ddi_name_to_major(i2o_bsa_name); - - /* - * Create minor nodes. - */ - if (create_minor_node(dip, bsadata) == DDI_FAILURE) { - goto out; - } - - /* get the capacity and type */ - - if (bsa_setup(bsadata)) { - - cmn_err(CE_CONT, "?bsa_attach: Unable to setup geometry\n"); - goto out; - } - - /* - * read the label - */ - mutex_enter(&bsadata->lbl.mutex); - if (update_vtoc(bsadata, makedevice(devmajor, - BSA_SETMINOR(bsadata->instance, FDISK_OFFSET)))) { - mutex_exit(&bsadata->lbl.mutex); - goto out; - } - mutex_exit(&bsadata->lbl.mutex); - - - /* - * Register to receive event notification - */ - - mask = I2O_EVENT_IND_STATE_CHANGE | I2O_EVENT_IND_DEVICE_STATE | - I2O_EVENT_IND_DEVICE_RESET | I2O_EVENT_IND_CAPABILITY_CHANGE | - I2O_BSA_EVENT_VOLUME_LOAD | I2O_BSA_EVENT_CAPACITY_CHANGE | - I2O_UTIL_EVENT_ACKNOWLEDGE | I2O_BSA_EVENT_VOLUME_UNLOAD; - - if (UtilEventRegister(bsadata, mask)) - cmn_err(CE_CONT, "?Could not register for event notification" - "for tid = %d\n", bsadata->tid); - - /* free up the resources */ - ddi_dma_mem_free(&acc_handle); - ddi_dma_free_handle(&dma_handle); - - return (DDI_SUCCESS); - -out: - /* - * release all dma resources - */ - - if (buf) - ddi_dma_mem_free(&acc_handle); - - if (dma_handle) - ddi_dma_free_handle(&dma_handle); - - if (bsadata) { - if (bsadata->flags & CLAIMED) - if (UtilClaim_release(bsadata)) { - cmn_err(CE_CONT, "?bsa_attach: Unable to" - "unclaim the %d device\n", - bsadata->tid); - - } - /* - * free the soft_state structure here. - */ - ddi_soft_state_free(bsa_soft, instance); - } - - if (handle) - i2o_msg_osm_unregister(&handle); - - return (DDI_FAILURE); - -} - -/* - * The detach routine for Block Storage - */ - -static int -bsa_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) -{ - int instance = ddi_get_instance(devi); - struct bsa_data *bsadata; - int event; - - - bsadata = ddi_get_soft_state(bsa_soft, instance); - - if (cmd == DDI_SUSPEND) { - /* - * Power down, unload: fully power down the device, unloading - * the volume, if present. - */ - if (BsaPowerMgt(bsadata, I2O_BSA_POWER_MGT_POWER_DOWN_UNLOAD)) - return (DDI_FAILURE); - - return (DDI_SUCCESS); - } - - if (cmd != DDI_DETACH) - return (EINVAL); - - /* - * Stop receiving any events of any category - */ - event = 0; - if (UtilEventRegister(bsadata, event)) { - - cmn_err(CE_CONT, "?bs_detach: Unable to stop receiving" - "events from IOP\n"); - return (DDI_FAILURE); - - - } - - /* - * Clean Wild Abort. Abort all messages form this initiator - * (any function, and TransactionContext). - */ - - if (UtilAbort(bsadata, I2O_ABORT_TYPE_CLEAN_WILD_ABORT, NULL, NULL)) { - cmn_err(CE_CONT, "?bs_detach: Unable to abort all messages\n"); - return (DDI_FAILURE); - } - - /* - * Release the device that Claimed in attach - */ - - if (UtilClaim_release(bsadata)) { - cmn_err(CE_CONT, "?bs_detach: Unable to unclaim the %d" - "device\n", bsadata->tid); - return (DDI_FAILURE); - - } - - i2o_msg_osm_unregister(&bsadata->iop); - - /* - * Remove all the minor nodes for this dip - */ - - ddi_remove_minor_node(devi, NULL); - - mutex_destroy(&bsadata->bsa_mutex); - mutex_destroy(&bsadata->lbl.mutex); - /* - * free the soft_state structure here. - */ - ddi_soft_state_free(bsa_soft, instance); - - DEBUGF(I2O_DEBUG_GEN, (CE_CONT, "?sucessfull detach\n")); - - return (DDI_SUCCESS); -} - - - -/* - * Parse the LCT to find the target id in bsadata. If the target id is - * available claim it. - */ - -/*ARGSUSED3*/ -static int -parse_lct(void * buf, size_t size, bsa_data_t *bsadata, - ddi_acc_handle_t acc_handle) -{ - - i2o_lct_entry_t *lctp; /* pointer to Logical cofiguration table */ - int ent; - int class; /* Class of the device */ - int localtid; /* The TID of the device */ - int usertid; /* User TID */ - int ret = 0; - - - bsadata->flags &= ~CLAIMED; - lctp = ((i2o_lct_t *)buf)->LCTEntry; - - /* - * get number of entries in the table - */ - ent = (size/sizeof (i2o_lct_entry_t)); - - DEBUGF(I2O_DEBUG_DINT, (CE_CONT, "?parse_lct:" - "parse_lct: number entries in the LCT = %d", ent)); - - while (ent) { - - class = get_lct_entry_Class(lctp, acc_handle); - if (class & I2O_CLASS_RANDOM_BLOCK_STORAGE) { - localtid = get_lct_entry_LocalTID(lctp, - acc_handle); - - /* Find the device by matching TID */ - if (localtid == bsadata->tid) { - usertid = get_lct_entry_UserTID(lctp, - acc_handle); - - /* If device is available claim it */ - if (usertid == 0xFFF) { - - if (ret = UtilClaim(bsadata)) { - cmn_err(CE_CONT, "?parse_lct:" - "could not claim the device" - "0x%x\n", bsadata->tid); - - return (ret); - } - bsadata->flags |= CLAIMED; - } else { - cmn_err(CE_CONT, "?parse_lct:" - "could not claim the device 0x%x." - "Device not available\n", - bsadata->tid); - return (-1); - - } - - break; - } - } - ent--; - lctp++; - } - - return (0); -} - -/* - * The open routine for Block storage - */ - - -/*ARGSUSED*/ -static int -bsa_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p) -{ - bsa_data_t *bsadata; - register dev_t dev = *dev_p; - int instance; - int ret = 0; - - /* - * get instance number - */ - instance = UNIT(dev); - - if ((bsadata = ddi_get_soft_state(bsa_soft, instance)) == NULL) { - return (ENXIO); - } - - mutex_enter(&bsadata->lbl.mutex); - if (bsadata->lbl.vtocread != 1) { - if (bsadata->lbl.geomread != 1) - (void) bsa_setup(bsadata); - (void) update_vtoc(bsadata, dev); - } - mutex_exit(&bsadata->lbl.mutex); - - mutex_enter(&bsadata->bsa_mutex); - - if (ISREMOVABLE(bsadata)) { - if (flag & FWRITE) { - if (ISCD(bsadata) || ISWRITEPROTECT(bsadata)) - return (EROFS); /* read only filesys */ - } - /* lock the device (close the door) on first open */ - if (bsadata->open_flag == 0) - ret = BsaMediaLock(bsadata); - bsadata->open_flag |= (1 << LPART(dev)); - if (ISCD(bsadata) && ret != 0) - return (ret); - } - mutex_exit(&bsadata->bsa_mutex); - - return (0); -} - -/* - * The close routine for Block Storage - */ - -/*ARGSUSED*/ -static int -bsa_close(dev_t dev, int flag, int otyp, cred_t *cred_p) -{ - bsa_data_t *bsadata; - int instance, ret; - - - /* - * get instance number - */ - instance = UNIT(dev); - - bsadata = ddi_get_soft_state(bsa_soft, instance); - if (ISREMOVABLE(bsadata)) { - mutex_enter(&bsadata->bsa_mutex); - bsadata->open_flag &= ~(1 << LPART(dev)); - if (bsadata->open_flag == 0) { - - ret = BsaMediaUnlock(bsadata); - if (ISCD(bsadata) && ret != 0) { - mutex_exit(&(bsadata)->bsa_mutex); - return (ENXIO); - } - - if (ISREMOVABLE(bsadata)) - (void) BsaMediaEject(bsadata); - - mutex_exit(&bsadata->bsa_mutex); - } - } - return (0); -} - -/* - * Convert the dev information - */ - -/*ARGSUSED*/ -static int -bsa_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void * arg, - void **result) -{ - bsa_data_t *bsadata; - - dev_t dev; - int instance, error; - - switch (infocmd) { - case DDI_INFO_DEVT2DEVINFO: - dev = (dev_t)arg; - instance = UNIT(dev); - if ((bsadata = ddi_get_soft_state(bsa_soft, instance)) == NULL) - return (DDI_FAILURE); - *result = (void *)bsadata->dip; - error = DDI_SUCCESS; - break; - case DDI_INFO_DEVT2INSTANCE: - dev = (dev_t)arg; - instance = UNIT(dev); - *result = (void *)(uintptr_t)instance; - error = DDI_SUCCESS; - break; - default: - error = DDI_FAILURE; - } - return (error); - -} - -static struct driver_minor_data { - char *name; - int minor; - int type; -} bsa_minor_data[] = { - { "a", 0, S_IFBLK}, - { "b", 1, S_IFBLK}, - { "c", 2, S_IFBLK}, - { "d", 3, S_IFBLK}, - { "e", 4, S_IFBLK}, - { "f", 5, S_IFBLK}, - { "g", 6, S_IFBLK}, - { "h", 7, S_IFBLK}, - { "a,raw", 0, S_IFCHR}, - { "b,raw", 1, S_IFCHR}, - { "c,raw", 2, S_IFCHR}, - { "d,raw", 3, S_IFCHR}, - { "e,raw", 4, S_IFCHR}, - { "f,raw", 5, S_IFCHR}, - { "g,raw", 6, S_IFCHR}, - { "h,raw", 7, S_IFCHR}, -#if defined(_SUNOS_VTOC_16) - { "i", 8, S_IFBLK}, - { "j", 9, S_IFBLK}, - { "k", 10, S_IFBLK}, - { "l", 11, S_IFBLK}, - { "m", 12, S_IFBLK}, - { "n", 13, S_IFBLK}, - { "o", 14, S_IFBLK}, - { "p", 15, S_IFBLK}, - { "q", 16, S_IFBLK}, - { "r", 17, S_IFBLK}, - { "s", 18, S_IFBLK}, - { "t", 19, S_IFBLK}, - { "u", 20, S_IFBLK}, - { "i,raw", 8, S_IFCHR}, - { "j,raw", 9, S_IFCHR}, - { "k,raw", 10, S_IFCHR}, - { "l,raw", 11, S_IFCHR}, - { "m,raw", 12, S_IFCHR}, - { "n,raw", 13, S_IFCHR}, - { "o,raw", 14, S_IFCHR}, - { "p,raw", 15, S_IFCHR}, - { "q,raw", 16, S_IFCHR}, - { "r,raw", 17, S_IFCHR}, - { "s,raw", 18, S_IFCHR}, - { "t,raw", 19, S_IFCHR}, - { "u,raw", 20, S_IFCHR}, -#endif - {0} - - }; - -/* - * Create the minor node for Block storage device - */ - -static int -create_minor_node(dev_info_t *dip, bsa_data_t *bsadata) -{ - char *node_type; - char name[48]; - struct driver_minor_data *dmdp; - - - if (bsadata->unitp.au_type == DKC_CDROM) - node_type = DDI_NT_CD; - else - node_type = DDI_NT_BLOCK; - - for (dmdp = bsa_minor_data; dmdp->name != NULL; dmdp++) { - (void) sprintf(name, "%s", dmdp->name); - if (ddi_create_minor_node(dip, name, dmdp->type, - BSA_SETMINOR(bsadata->instance, dmdp->minor), - node_type, NULL) == DDI_FAILURE) { - return (DDI_FAILURE); - } - } - - return (DDI_SUCCESS); -} - -/* - * Print routine for Block storage device - */ - - -static int -bsa_print(dev_t dev, char *str) -{ - int instance; - struct bsa_data *bsadata; - - - /* - * get instance number - */ - instance = UNIT(dev); - - if (!(bsadata = ddi_get_soft_state(bsa_soft, instance))) { - return (ENXIO); - } - - - cmn_err(CE_NOTE, "bsa_print: target id %d %s", bsadata->tid, str); - return (0); - -} - -/* - * Used the minphys (MAX transfer for the system) for the MAX transfer since - * the OSM sends everthing to IOP. It is the responsibility of HDM or ISM - * (DDM) to take care of limitation of the device. - */ - -static int -bsa_rdrw(dev_t dev, struct uio *uio, int flag) -{ - register int secmask; - secmask = DEV_BSIZE - 1; - - if (uio->uio_loffset & ((offset_t)(secmask))) { - DEBUGF(I2O_DEBUG_DIO, (CE_CONT, "?bsa_rdrw:" - "file offset not modulo %d\n", DEV_BSIZE)); - return (EINVAL); - } else if (uio->uio_iov->iov_len & (secmask)) { - DEBUGF(I2O_DEBUG_DIO, (CE_CONT, "bsa_rdrw:" - "transfer length not modulo %d\n", DEV_BSIZE)); - return (EINVAL); - } - return (physio(bsa_strategy, (struct buf *)0, dev, flag, - minphys, uio)); -} - -/* - * Read routine for Block Storage device - */ - -/*ARGSUSED2*/ -static int -bsa_read(dev_t dev, struct uio *uio, cred_t *cred_p) -{ - return (bsa_rdrw(dev, uio, B_READ)); -} - -/* - * Write routine for Block Storage device - */ - -/*ARGSUSED2*/ -static int -bsa_write(dev_t dev, struct uio *uio, cred_t *cred_p) -{ - return (bsa_rdrw(dev, uio, B_WRITE)); -} - -/* - * Dump routine for Block Storage device - */ - -static int -bsa_dump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk) -{ - struct bsa_data *bsadata; - struct buf *bp; - int instance; - - - /* - * get instance number - */ - instance = UNIT(dev); - - bsadata = ddi_get_soft_state(bsa_soft, instance); - - - if (!bsadata) { - return (ENXIO); - } - - bp = bsadata->crashbuf; - bp->b_un.b_addr = addr; - bp->b_edev = dev; - bp->b_dev = cmpdev(dev); - bp->b_bcount = nblk * DEV_BSIZE; - bp->b_flags = B_WRITE | B_PHYS; - bp->b_blkno = blkno; - bp->b_private = 0; - (void) bsa_strategy(bp); - - for (;;) { - drv_usecwait(1000); - if (bp->b_flags & B_DONE) { - if (bp->b_flags & B_ERROR) - return (bp->b_error); - else - return (0); - } - } -} - - -/* - * Get device parameters. This is where BSA acquire device information - */ -static int -UtilParamsGet(bsa_data_t *bsadata) -{ - i2o_msg_handle_t msg_handle; - ddi_acc_handle_t acc_handle; - uint_t versionoffset; - bsa_context_t *tcontextp; - i2o_sge_simple_element_t *segemp = NULL; - int sg2bind = 0; - int sgbind = 0; - void *resbuf, *opbuf = NULL; /* result buffer */ - size_t real_length; - uint_t sg2ncookies = 0; - uint_t sgncookies = 0; - ddi_dma_cookie_t dma_sgcookie; - ddi_dma_cookie_t dma_sg2cookie; - struct bsa_unit *bsa_unitp; /* phsyical characteristics */ - i2o_util_params_get_message_t *msgbuf = NULL; - - - void *resptr; /* opaque ptr */ - - i2o_bsa_device_info_scalar_t *resptr1; - i2o_param_operation_all_template_t *opbufptr1; - i2o_param_operations_list_header_t *opbufptr; - - int ret = DDI_SUCCESS; - -#if I2O_64BIT_CONTEXT - versionoffset = 0x71; -#else - versionoffset = 0x51; -#endif - - /* - * Allocate a message frame from IOP's inbound queue - * Sleep until the resource is available - */ - - if (i2o_msg_alloc(bsadata->iop, I2O_MSG_SLEEP, NULL, (void **)&msgbuf, - &msg_handle, &acc_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?UtilParamsGet: Frame buffer " - "resource not available\n"); - return (-1); - - } - - /* - * Set up the Standard Message frame fields - */ - - setup_msghdr(I2O_UTIL_PARAMS_GET, UtilParamsGet_reply, - &msgbuf->StdMessageFrame, acc_handle, versionoffset, - bsadata->tid, 0, sizeof (i2o_util_params_get_message_t) + - (2 * sizeof (i2o_sge_simple_element_t)) - - sizeof (i2o_sg_element_t)); - - /* - * Set the Transaction Context field (used for reply correlation) - */ - - tcontextp = (struct bsa_context *) - kmem_zalloc(sizeof (bsa_context_t), KM_SLEEP); - - tcontextp->bsadata = bsadata; - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContext, - (uint64_t)tcontextp); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContext, - (uint32_t)(uintptr_t)tcontextp); -#endif - - /* - * Allocate buffer for the Operation list which consist of - * Operation_list_header and operation_specific_template - * Later on may want to use immediate Data Element. - */ - - if ((ddi_dma_alloc_handle(tcontextp->bsadata->dip, &dma_attr_sglfrm, - DDI_DMA_SLEEP, 0, &tcontextp->dma_sghandle)) != DDI_SUCCESS) { - - ret = ENOMEM; - cmn_err(CE_CONT, "?UtilParamsGet: No resources " - "available\n"); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - } - - - if ((ddi_dma_mem_alloc(tcontextp->dma_sghandle, - (sizeof (i2o_param_operations_list_header_t) + - sizeof (i2o_param_operation_all_template_t)), - &accattr, DDI_DMA_STREAMING, DDI_DMA_SLEEP, 0, - (caddr_t *)&opbuf, &real_length, &tcontextp->acc_sghandle)) - != DDI_SUCCESS) { - - ret = ENOMEM; - cmn_err(CE_CONT, "?UtilParamsGet: No resources " - "available\n"); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - } - - /* - * Initialize the Operation Block structure. - * We only have one operation (which is for SCALAR INFO) so the - * Operationcount is 1 - */ - - ddi_put16(tcontextp->acc_sghandle, - &((i2o_param_operations_list_header_t *)opbuf)->OperationCount, 1); - - opbufptr = (void *)((char *)opbuf - + sizeof (i2o_param_operations_list_header_t)); - - opbufptr1 = (i2o_param_operation_all_template_t *)opbufptr; - - ddi_put16(tcontextp->acc_sghandle, - &opbufptr1->Operation, I2O_PARAMS_OPERATION_FIELD_GET); - - ddi_put16(tcontextp->acc_sghandle, - &opbufptr1->GroupNumber, I2O_BSA_DEVICE_INFO_GROUP_NO); - - /* - * For now lets return all fields we have 64-12 bytes available - */ - - ddi_put16(tcontextp->acc_sghandle, &opbufptr1->FieldCount, -1); - - - ret = ddi_dma_addr_bind_handle(tcontextp->dma_sghandle, NULL, - (caddr_t)opbuf, real_length, - DDI_DMA_WRITE | DDI_DMA_STREAMING, DDI_DMA_SLEEP, 0, - &dma_sgcookie, &sgncookies); - - switch (ret) { - case DDI_DMA_MAPPED: - /* - * This flag used in case of error to unbind the DMA - * handle The address is bound to DMA handle - */ - sgbind = 1; - break; - case DDI_DMA_NORESOURCES: - ret = ENOMEM; - cmn_err(CE_CONT, "?UtilParamsGet:" - " No DMA resources available\n"); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - - case DDI_DMA_INUSE: - case DDI_DMA_TOOBIG: - ret = ENOMEM; - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - - case DDI_DMA_NOMAPPING: - default: - ret = EFAULT; - cmn_err(CE_CONT, "?UtilParamsGet:" - " DMA failed 0x%x\n", ret); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - - goto out; - } - - - segemp = msgbuf->SGL.u1.Simple; - - - /* - * fill out the first SG element in the frame - */ - - put_flags_count_Count(&segemp->FlagsCount, - real_length, acc_handle); - - put_flags_count_Flags(&segemp->FlagsCount, - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT | - I2O_SGL_FLAGS_END_OF_BUFFER, - acc_handle); - - ddi_put32(acc_handle, &segemp->PhysicalAddress, - dma_sgcookie.dmac_address); - - - /* - * Setup the result buffer. - */ - - if ((ddi_dma_alloc_handle(tcontextp->bsadata->dip, &dma_attr_sglfrm, - DDI_DMA_SLEEP, 0, &tcontextp->dma_sg2handle)) != DDI_SUCCESS) { - - ret = ENOMEM; - cmn_err(CE_CONT, "?UtilParamsGet: No resources " - "available\n"); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - } - - /* - * allocate the result buffer - */ - if ((ddi_dma_mem_alloc(tcontextp->dma_sg2handle, - ((sizeof (i2o_param_results_list_header_t)) + - (sizeof (i2o_param_read_operation_result_t)) + - (sizeof (i2o_bsa_device_info_scalar_t)) + - (sizeof (i2o_param_error_info_template_t))), - &accattr, DDI_DMA_STREAMING, DDI_DMA_SLEEP, 0, - (caddr_t *)&resbuf, &real_length, &tcontextp->acc_sg2handle)) - != DDI_SUCCESS) { - - ret = ENOMEM; - cmn_err(CE_CONT, "?UtilParamsGet: No resources " - "available\n"); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - } - - - ret = ddi_dma_addr_bind_handle(tcontextp->dma_sg2handle, NULL, - (caddr_t)resbuf, real_length, - DDI_DMA_READ | DDI_DMA_STREAMING, DDI_DMA_SLEEP, 0, - &dma_sg2cookie, &sg2ncookies); - - switch (ret) { - case DDI_DMA_MAPPED: - /* - * This flag used in case of error to unbind the DMA - * handle The address is bound to DMA handle - */ - sg2bind = 1; - break; - case DDI_DMA_NORESOURCES: - ret = ENOMEM; - cmn_err(CE_CONT, "?UtilParamsGet:" - " No DMA resources available\n"); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - - case DDI_DMA_INUSE: - case DDI_DMA_TOOBIG: - ret = ENOMEM; - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - - case DDI_DMA_NOMAPPING: - default: - ret = EFAULT; - cmn_err(CE_CONT, "?UtilParamsGet:" - " DMA failed 0x%x\n", ret); - if (msgbuf) - UtilNOP(bsadata->iop, acc_handle, - (i2o_common_message_t *)msgbuf, msg_handle); - goto out; - } - - segemp++; - - /* - * fill out the second SG element in the frame (The result buf) - */ - - put_flags_count_Count(&segemp->FlagsCount, - real_length, acc_handle); - - put_flags_count_Flags(&segemp->FlagsCount, - I2O_SGL_FLAGS_LAST_ELEMENT | - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT | - I2O_SGL_FLAGS_END_OF_BUFFER, - acc_handle); - - /* - * Physical address for resbuf - */ - - ddi_put32(acc_handle, &segemp->PhysicalAddress, - dma_sg2cookie.dmac_address); - - - if (i2o_msg_send(bsadata->iop, msgbuf, msg_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?UtilParamsGet: i2o_msg_send failed"); - ret = DDI_FAILURE; - goto out; - - } - - /* - * do a cv_wait here for reply - */ - - mutex_enter(&bsadata->bsa_mutex); - while (!(tcontextp->replyflag & REPLY_DONE)) - cv_wait(&bsadata->reply_cv, &bsadata->bsa_mutex); - tcontextp->replyflag &= ~REPLY_DONE; - mutex_exit(&bsadata->bsa_mutex); - - if ((ret = tcontextp->retval) != 0) - goto out; - - resptr = (void *)((char *)resbuf - + sizeof (i2o_param_results_list_header_t) - + sizeof (i2o_param_read_operation_result_t)); - - resptr1 = (i2o_bsa_device_info_scalar_t *)resptr; - - /* - * Sync the DMA memory - */ - - (void) ddi_dma_sync(tcontextp->dma_sg2handle, 0, real_length, - DDI_DMA_SYNC_FORCPU); - - /* - * ParamsGet will be called only from attach(9F). - */ - - mutex_enter(&tcontextp->bsadata->bsa_mutex); - - bsa_unitp = &tcontextp->bsadata->unitp; - - bsa_unitp->au_blksize = ddi_get32(tcontextp->acc_sg2handle, - &resptr1->BlockSize); - - bsa_unitp->au_type = ddi_get8(tcontextp->acc_sg2handle, - &resptr1->DeviceType); - - bsa_unitp->au_capacity = - ddi_get64(tcontextp->acc_sg2handle, - &resptr1->DeviceCapacity); - - bsa_unitp->au_devicecapability = - ddi_get32(tcontextp->acc_sg2handle, - &resptr1->DeviceCapabilitySupport); - - mutex_exit(&tcontextp->bsadata->bsa_mutex); - - DEBUGF(I2O_DEBUG_DIO, (CE_CONT, "?ParamsGet:" - "capability = 0x%x capacity = 0x%llx" - "type = 0x%x block size = <%d> <%x>\n", - bsa_unitp->au_devicecapability, - bsa_unitp->au_capacity, - bsa_unitp->au_type, - bsa_unitp->au_blksize)); - - - if (tcontextp->dma_handle) { - (void) ddi_dma_unbind_handle(tcontextp->dma_handle); - ddi_dma_free_handle(&tcontextp->dma_handle); - } - - - (void) ddi_dma_unbind_handle(tcontextp->dma_sghandle); - - ddi_dma_mem_free(&tcontextp->acc_sghandle); - - ddi_dma_free_handle(&tcontextp->dma_sghandle); - - (void) ddi_dma_unbind_handle(tcontextp->dma_sg2handle); - - ddi_dma_mem_free(&tcontextp->acc_sg2handle); - - ddi_dma_free_handle(&tcontextp->dma_sg2handle); - - kmem_free(tcontextp, sizeof (bsa_context_t)); - - - return (DDI_SUCCESS); - -out: - - if (tcontextp->dma_handle) { - (void) ddi_dma_unbind_handle(tcontextp->dma_handle); - ddi_dma_free_handle(&tcontextp->dma_handle); - } - - if (sgbind) - (void) ddi_dma_unbind_handle(tcontextp->dma_sghandle); - if (opbuf) - ddi_dma_mem_free(&tcontextp->acc_sghandle); - if (tcontextp->dma_sghandle) - ddi_dma_free_handle(&tcontextp->dma_sghandle); - - if (sg2bind) - (void) ddi_dma_unbind_handle(tcontextp->dma_sg2handle); - if (resbuf) - ddi_dma_free_handle(&tcontextp->dma_sg2handle); - - if (tcontextp) - kmem_free(tcontextp, sizeof (bsa_context_t)); - - return (ret); -} - -/* - * The reply message for UtilParamsGet - */ - - - -static void -UtilParamsGet_reply(void *msg, ddi_acc_handle_t acc_handle) -{ - - bsa_context_t *tcontextp; - int detstatus, reqstatus; - - /* - * Get the Transacton Context field - */ - -#if I2O_64BIT_CONTEXT - tcontextp = (bsa_context_t *)ddi_get64(acc_handle, - &(((i2o_single_reply_message_frame_t *)msg)->TransactiontContext)); -#else - tcontextp = (bsa_context_t *)(uintptr_t)ddi_get32(acc_handle, - &(((i2o_single_reply_message_frame_t *)msg)->TransactionContext)); -#endif - - /* - * Detailed status - */ - detstatus = ddi_get16(acc_handle, - &((i2o_single_reply_message_frame_t *)msg)->DetailedStatusCode); - - /* - * reply status - */ - reqstatus = ddi_get8(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->ReqStatus); - - tcontextp->retval = translate_error(reqstatus, detstatus, 1); - - mutex_enter(&tcontextp->bsadata->bsa_mutex); - tcontextp->replyflag |= REPLY_DONE; - cv_broadcast(&tcontextp->bsadata->reply_cv); - mutex_exit(&tcontextp->bsadata->bsa_mutex); - -} - -/* - * Claim the BSA device. - */ - -static int -UtilClaim(bsa_data_t *bsadata) -{ - bsa_context_t *tcontextp; - ddi_acc_handle_t acc_handle; - i2o_msg_handle_t msg_handle; - i2o_util_claim_message_t *msgbuf; - int ret = DDI_SUCCESS; - - ret = 0; - - /* - * Allocate a message frame from IOP's inbound queue - * Sleep until the resource is available - */ - - if (i2o_msg_alloc(bsadata->iop, I2O_MSG_SLEEP, NULL, (void **)&msgbuf, - &msg_handle, &acc_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?UtilClaim: Frame buffer " - "resource not available\n"); - return (-1); - - } - - /* - * Set up the Standard Message frame fields - */ - - setup_msghdr(I2O_UTIL_CLAIM, UtilClaim_reply, - &msgbuf->StdMessageFrame, acc_handle, 0x01, - bsadata->tid, 0, sizeof (i2o_util_claim_message_t)); - - - /* - * For now be the exclusive user - */ - ddi_put16(acc_handle, &msgbuf->ClaimFlags, - I2O_CLAIM_FLAGS_EXCLUSIVE); - - /* - * For now be the primary user - */ - ddi_put8(acc_handle, &msgbuf->ClaimType, - I2O_CLAIM_TYPE_PRIMARY_USER); - - /* Set the Transaction Context field (used for reply correlation) */ - - tcontextp = (struct bsa_context *) - kmem_zalloc(sizeof (bsa_context_t), KM_SLEEP); - tcontextp->bsadata = bsadata; - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContext, - (uint64_t)tcontextp); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContext, - (uint32_t)(uintptr_t)tcontextp); -#endif - - if (i2o_msg_send(bsadata->iop, msgbuf, msg_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?UtilClaim: i2o_msg_send failed"); - return (DDI_FAILURE); - } - - /* - * do a cv_wait here for reply - */ - mutex_enter(&bsadata->bsa_mutex); - while (!(tcontextp->replyflag & REPLY_DONE)) - cv_wait(&bsadata->reply_cv, &bsadata->bsa_mutex); - tcontextp->replyflag &= ~REPLY_DONE; - mutex_exit(&bsadata->bsa_mutex); - - ret = tcontextp->retval; - - kmem_free((caddr_t)tcontextp, sizeof (bsa_context_t)); - - return (ret); -} - -/* - * Unclaim the device - */ - -static int -UtilClaim_release(bsa_data_t *bsadata) -{ - bsa_context_t *tcontextp; - ddi_acc_handle_t acc_handle; - i2o_msg_handle_t msg_handle; - - i2o_util_claim_release_message_t *msgbuf; - int ret = DDI_SUCCESS; - - /* - * Allocate a message frame from IOP's inbound queue - * Sleep until the resource is available - */ - - if (i2o_msg_alloc(bsadata->iop, I2O_MSG_SLEEP, NULL, (void **)&msgbuf, - &msg_handle, &acc_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?UtilClaim_release: Frame buffer " - "resource not available\n"); - return (-1); - - } - - /* - * Set up the Standard Message frame fields - */ - - setup_msghdr(I2O_UTIL_CLAIM_RELEASE, UtilClaim_release_reply, - &msgbuf->StdMessageFrame, acc_handle, 0x01, - bsadata->tid, 0, sizeof (i2o_util_claim_release_message_t)); - - - /* - * For now be the primary user - */ - ddi_put8(acc_handle, &msgbuf->ClaimType, I2O_CLAIM_TYPE_PRIMARY_USER); - - /* - * Set the Transaction Context field (used for reply correlation) - */ - - tcontextp = (bsa_context_t *)kmem_zalloc(sizeof (bsa_context_t), - KM_SLEEP); - tcontextp->bsadata = bsadata; - - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContext, - (uint64_t)tcontextp); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContext, - (uint32_t)(uintptr_t)tcontextp); -#endif - - if (i2o_msg_send(bsadata->iop, msgbuf, msg_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?UtilClaim_release: i2o_msg_send failed"); - return (DDI_FAILURE); - } - - /* - * do a cv_wait here for reply - */ - mutex_enter(&bsadata->bsa_mutex); - while (!(tcontextp->replyflag & REPLY_DONE)) - cv_wait(&bsadata->reply_cv, &bsadata->bsa_mutex); - tcontextp->replyflag &= ~REPLY_DONE; - mutex_exit(&bsadata->bsa_mutex); - - ret = tcontextp->retval; - - kmem_free(tcontextp, sizeof (bsa_context_t)); - - return (ret); - -} - - -/* - * UtilClaim_release reply. The reply routine for UtilClaim_release - */ - -static void -UtilClaim_release_reply(void *msg, ddi_acc_handle_t acc_handle) -{ - - bsa_context_t *tcontextp; - int detstatus, reqstatus; - -#if I2O_64BIT_CONTEXT - tcontextp = (bsa_context_t *)ddi_get64(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactiontContext)); -#else - tcontextp = (bsa_context_t *)(uintptr_t)ddi_get32(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactionContext)); -#endif - - - /* - * Detailed status - */ - detstatus = ddi_get16(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->DetailedStatusCode); - - /* - * reply status - */ - reqstatus = ddi_get8(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->ReqStatus); - - tcontextp->retval = translate_error(reqstatus, detstatus, 1); - - mutex_enter(&tcontextp->bsadata->bsa_mutex); - tcontextp->replyflag |= REPLY_DONE; - cv_broadcast(&tcontextp->bsadata->reply_cv); - mutex_exit(&tcontextp->bsadata->bsa_mutex); -} - -/* - * Reply routine for UtilClaim - */ - -static void -UtilClaim_reply(void *msg, ddi_acc_handle_t acc_handle) -{ - bsa_context_t *tcontextp; - int detstatus, reqstatus; - -#if I2O_64BIT_CONTEXT - tcontextp = (bsa_context_t *)ddi_get64(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactiontContext)); -#else - tcontextp = (bsa_context_t *)(uintptr_t)ddi_get32(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactionContext)); -#endif - - /* - * Detailed status - */ - detstatus = ddi_get16(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->DetailedStatusCode); - /* - * reply status - */ - reqstatus = ddi_get8(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->ReqStatus); - - tcontextp->retval = translate_error(reqstatus, detstatus, 1); - - mutex_enter(&tcontextp->bsadata->bsa_mutex); - tcontextp->replyflag |= REPLY_DONE; - cv_broadcast(&tcontextp->bsadata->reply_cv); - mutex_exit(&tcontextp->bsadata->bsa_mutex); - -} - -/* - * Abort specific messages. (ie. TransactionContext) - */ - -static int -UtilAbort(bsa_data_t *bsadata, int aborttype, uint8_t functoabort, - uint64_t TransactionContextToAbort) -{ - bsa_context_t *tcontextp; - ddi_acc_handle_t acc_handle; - i2o_msg_handle_t msg_handle; - i2o_util_abort_message_t *msgbuf; - int ret = DDI_SUCCESS; - - /* - * Allocate a message frame from IOP's inbound queue - * Sleep until the resource is available - */ - - if (i2o_msg_alloc(bsadata->iop, I2O_MSG_SLEEP, NULL, (void **)&msgbuf, - &msg_handle, &acc_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?UtilAbort: Frame buffer " - "resource not available\n"); - return (-1); - } - - /* - * Set up the Standard Message frame fields - */ - - setup_msghdr(I2O_UTIL_ABORT, UtilAbort_reply, - &msgbuf->StdMessageFrame, acc_handle, 0x01, - bsadata->tid, 0, sizeof (i2o_util_abort_message_t)); - - ddi_put8(acc_handle, &msgbuf->AbortType, aborttype); - - ddi_put8(acc_handle, &msgbuf->FunctionToAbort, functoabort); - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContextToAbort, - TransactionContextToAbort); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContextToAbort, - TransactionContextToAbort); - -#endif - - /* - * Set the Transaction Context field (used for reply correlation) - */ - - tcontextp = (bsa_context_t *)kmem_zalloc(sizeof (bsa_context_t), - KM_SLEEP); - tcontextp->bsadata = bsadata; - - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContext, - (uint64_t)tcontextp); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContext, - (uint32_t)(uintptr_t)tcontextp); -#endif - - if (i2o_msg_send(bsadata->iop, msgbuf, msg_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?UtilAbort: i2o_msg_send failed"); - return (DDI_FAILURE); - } - - /* - * do a cv_wait here for reply - */ - mutex_enter(&bsadata->bsa_mutex); - while (!(tcontextp->replyflag & REPLY_DONE)) - cv_wait(&bsadata->reply_cv, &bsadata->bsa_mutex); - tcontextp->replyflag &= ~REPLY_DONE; - mutex_exit(&bsadata->bsa_mutex); - - kmem_free(tcontextp, sizeof (bsa_context_t)); - - return (ret); -} - -/* - * The reply routine for UtilAbort - */ - -static void -UtilAbort_reply(void *msg, ddi_acc_handle_t acc_handle) -{ - - bsa_context_t *tcontextp; - int count; - - /* - * Get the Transacton Context field - */ -#if I2O_64BIT_CONTEXT - tcontextp = (bsa_context_t *)ddi_get64(acc_handle, - &(((i2o_util_abort_reply_t *) - msg)->TransactiontContext)); -#else - tcontextp = (bsa_context_t *)(uintptr_t)ddi_get32(acc_handle, - &(((i2o_util_abort_reply_t *) - msg)->TransactionContext)); -#endif - - /* - * count of aborted messages - */ - count = ddi_get32(acc_handle, - &((i2o_util_abort_reply_t *) - msg)->CountOfAbortedMessages); - - cmn_err(CE_CONT, "?UtilAbort: number of messages aborted 0x%x", count); - - mutex_enter(&tcontextp->bsadata->bsa_mutex); - tcontextp->replyflag |= REPLY_DONE; - cv_broadcast(&tcontextp->bsadata->reply_cv); - mutex_exit(&tcontextp->bsadata->bsa_mutex); -} - -/* - * Register all the events you want to be informed of - * Note that a single OSM must use the same InitiatorContext and - * TransactionCOntext for all UtilEventRegoster requests (6-14) - */ - -static int -UtilEventRegister(bsa_data_t *bsadata, int event) -{ - - ddi_acc_handle_t acc_handle; - i2o_msg_handle_t msg_handle; - i2o_util_event_register_message_t *msgbuf; - int ret = DDI_SUCCESS; - - mutex_enter(&bsadata->bsa_mutex); - - /* - * Allocate a message frame from IOP's inbound queue - * Sleep until the resource is available - */ - - if (i2o_msg_alloc(bsadata->iop, I2O_MSG_SLEEP, NULL, (void **)&msgbuf, - &msg_handle, &acc_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?UtilEventRegister: Frame buffer " - "resource not available\n"); - return (-1); - } - - /* - * Set up the Standard Message frame fields - */ - - setup_msghdr(I2O_UTIL_EVENT_REGISTER, UtilEventRegister_reply, - &msgbuf->StdMessageFrame, acc_handle, 0x01, - bsadata->tid, 0, sizeof (i2o_util_event_register_message_t)); - - - ddi_put32(acc_handle, &msgbuf->EventMask, event); - - /* Set the Transaction Context field (used for reply correlation) */ - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContext, - (uint64_t)bsadata); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContext, - (uint32_t)(uintptr_t)bsadata); -#endif - - if (i2o_msg_send(bsadata->iop, msgbuf, msg_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?UtilEventRegister: i2o_msg_send failed"); - return (DDI_FAILURE); - } - - mutex_exit(&bsadata->bsa_mutex); - - return (ret); -} - -/* - * Reply routine for UtilEventRegister routine - */ - - -static void -UtilEventRegister_reply(void *msg, ddi_acc_handle_t acc_handle) -{ - - uint32_t eventind; - uint32_t eventdata; - bsa_data_t *bsadata; - - /* - * Get the Transacton Context field - */ -#if I2O_64BIT_CONTEXT - bsadata = (bsa_context_t *)ddi_get64(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactiontContext)); -#else - bsadata = (bsa_data_t *)(uintptr_t)ddi_get32(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactionContext)); -#endif - /* - * Event indicator status - */ - eventind = ddi_get32(acc_handle, - &((i2o_util_event_register_reply_t *) - msg)->EventIndicator); - - switch (eventind) { - - case I2O_EVENT_IND_STATE_CHANGE: - eventdata = ddi_get32(acc_handle, - ((i2o_util_event_register_reply_t *) - msg)->EventData); - cmn_err(CE_CONT, "? The state of the device has changed" - "Error Code 0x%x\n", eventdata); - break; - case I2O_EVENT_IND_DEVICE_STATE: - eventdata = ddi_get32(acc_handle, - ((i2o_util_event_register_reply_t *) - msg)->EventData); - cmn_err(CE_CONT, "? The generic state of the device" - "has changed. Error Code 0x%x\n", eventdata); - break; - case I2O_EVENT_IND_DEVICE_RESET: - cmn_err(CE_CONT, "? A device reset has occured\n"); - break; - case I2O_EVENT_IND_CAPABILITY_CHANGE: - eventdata = ddi_get32(acc_handle, - ((i2o_util_event_register_reply_t *) - msg)->EventData); - cmn_err(CE_WARN, "?One or more capability has changed." - "Error Code 0x%x\n", eventdata); - break; - case I2O_BSA_EVENT_VOLUME_LOAD: - cmn_err(CE_CONT, "?New medium has been loaded" - "onto the device\n"); - mutex_enter(&bsadata->bsa_mutex); - bsadata->state = DKIO_INSERTED; - bsadata->flags |= STATE_CHANGE; - cv_broadcast(&bsadata->state_cv); - mutex_exit(&bsadata->bsa_mutex); - break; - case I2O_BSA_EVENT_CAPACITY_CHANGE: - cmn_err(CE_WARN, "?The capacity of the device has changed\n"); - break; - case I2O_BSA_EVENT_VOLUME_UNLOAD: - cmn_err(CE_CONT, "?The medium on the device has been" - "unloaded\n"); - mutex_enter(&bsadata->bsa_mutex); - bsadata->state = DKIO_EJECTED; - bsadata->flags |= STATE_CHANGE; - cv_broadcast(&bsadata->state_cv); - mutex_exit(&bsadata->bsa_mutex); - break; - } -} - -/* - * This Media Eject routine - */ - - -static int -BsaMediaEject(bsa_data_t *bsadata) -{ - bsa_context_t *tcontextp; - ddi_acc_handle_t acc_handle; - i2o_msg_handle_t msg_handle; - i2o_bsa_media_eject_message_t *msgbuf; - int ret = DDI_SUCCESS; - - - /* - * Allocate a message frame from IOP's inbound queue - * Sleep until the resource is available - */ - - if (i2o_msg_alloc(bsadata->iop, I2O_MSG_SLEEP, NULL, (void **)&msgbuf, - &msg_handle, &acc_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?BsaMediaEject: Frame buffer " - "resource not available\n"); - return (-1); - } - - /* - * Set up the Standard Message frame fields - */ - - setup_msghdr(I2O_BSA_MEDIA_EJECT, BsaMediaEject_reply, - &msgbuf->StdMessageFrame, acc_handle, 0x01, - bsadata->tid, 0, sizeof (i2o_bsa_media_eject_message_t)); - - /* - * Eject whatever currently mounted on the drive - */ - ddi_put32(acc_handle, &msgbuf->MediaIdentifier, - I2O_BSA_MEDIA_ID_CURRENT_MOUNTED); - - /* - * Set the Transaction Context field (used for reply correlation) - */ - - tcontextp = (bsa_context_t *)kmem_zalloc(sizeof (bsa_context_t), - KM_SLEEP); - tcontextp->bsadata = bsadata; - - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContext, - (uint64_t)tcontextp); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContext, - (uint32_t)(uintptr_t)tcontextp); -#endif - - - if (i2o_msg_send(bsadata->iop, msgbuf, msg_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?BsaMediaEject: i2o_msg_send failed"); - return (DDI_FAILURE); - } - - /* - * do a cv_wait here for reply - */ - mutex_enter(&bsadata->bsa_mutex); - while (!(tcontextp->replyflag & REPLY_DONE)) - cv_wait(&bsadata->reply_cv, &bsadata->bsa_mutex); - tcontextp->replyflag &= ~REPLY_DONE; - mutex_exit(&bsadata->bsa_mutex); - - ret = tcontextp->retval; - - kmem_free(tcontextp, sizeof (bsa_context_t)); - - return (ret); -} - -/* - * Media Eject reply routine - */ - -static void -BsaMediaEject_reply(void *msg, ddi_acc_handle_t acc_handle) -{ - bsa_context_t *tcontextp; - int detstatus, reqstatus; - - /* - * Get the Transacton Context field - */ -#if I2O_64BIT_CONTEXT - tcontextp = (bsa_context_t *)ddi_get64(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactiontContext)); -#else - tcontextp = (bsa_context_t *)(uintptr_t)ddi_get32(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactionContext)); -#endif - - /* - * Detailed status - */ - detstatus = ddi_get16(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->DetailedStatusCode); - - /* - * reply status - */ - reqstatus = ddi_get8(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->ReqStatus); - - mutex_enter(&tcontextp->bsadata->bsa_mutex); - if (reqstatus & I2O_REPLY_STATUS_SUCCESS) - tcontextp->bsadata->state = DKIO_EJECTED; - - tcontextp->retval = translate_error(reqstatus, detstatus, 0); - - tcontextp->replyflag |= REPLY_DONE; - cv_broadcast(&tcontextp->bsadata->reply_cv); - mutex_exit(&tcontextp->bsadata->bsa_mutex); -} - - -/* - * Power management for I2O - * DDI_RESUME: I2O_BSA_POWER_MGT_POWER_UP_LOAD: - * Power up, load: power up the device completely and load medium, - * if present. - * DDI_SUSPEND: I2O_BSA_POWER_MGT_POWER_DOWN_UNLOAD: - * Power down, unload: fully power down the device, unloading the - * valume, if present. - */ - -static int -BsaPowerMgt(bsa_data_t *bsadata, int operation) -{ - bsa_context_t *tcontextp; - ddi_acc_handle_t acc_handle; - i2o_msg_handle_t msg_handle; - i2o_bsa_power_management_message_t *msgbuf; - int ret = DDI_SUCCESS; - - /* - * Allocate a message frame from IOP's inbound queue - * Sleep until the resource is available - */ - - if (i2o_msg_alloc(bsadata->iop, I2O_MSG_SLEEP, NULL, (void **)&msgbuf, - &msg_handle, &acc_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?BsaPowerMgt: Frame buffer " - "resource not available\n"); - return (-1); - } - - /* - * Set up the Standard Message frame fields - */ - - setup_msghdr(I2O_BSA_POWER_MANAGEMENT, BsaPowerMgt_reply, - &msgbuf->StdMessageFrame, acc_handle, 0x01, - bsadata->tid, 0, sizeof (i2o_bsa_power_management_message_t)); - - - ddi_put8(acc_handle, &msgbuf->Operation, operation); - - /* - * Set the Transaction Context field (used for reply correlation) - */ - - tcontextp = (bsa_context_t *)kmem_zalloc(sizeof (bsa_context_t), - KM_SLEEP); - tcontextp->bsadata = bsadata; - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContext, - (uint64_t)tcontextp); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContext, - (uint32_t)(uintptr_t)tcontextp); -#endif - ddi_put8(acc_handle, &msgbuf->TimeMultiplier, 1); - - - if (i2o_msg_send(bsadata->iop, msgbuf, msg_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?BsaPowerMgt: i2o_msg_send failed"); - return (DDI_FAILURE); - } - - /* - * do a cv_wait here from reply - */ - mutex_enter(&bsadata->bsa_mutex); - while (!(tcontextp->replyflag & REPLY_DONE)) - cv_wait(&bsadata->reply_cv, &bsadata->bsa_mutex); - tcontextp->replyflag &= ~REPLY_DONE; - mutex_exit(&bsadata->bsa_mutex); - - ret = tcontextp->retval; - - kmem_free(tcontextp, sizeof (bsa_context_t)); - - return (ret); -} - -/* - * Power management reply routine - */ - -static void -BsaPowerMgt_reply(void *msg, ddi_acc_handle_t acc_handle) -{ - - - bsa_context_t *tcontextp; - int detstatus, reqstatus; - - - /* - * Get the Transacton Context field - */ -#if I2O_64BIT_CONTEXT - tcontextp = (bsa_context_t *)ddi_get64(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactiontContext)); -#else - tcontextp = (bsa_context_t *)(uintptr_t)ddi_get32(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactionContext)); -#endif - - /* - * Detailed status - */ - detstatus = ddi_get16(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->DetailedStatusCode); - - /* - * reply status - */ - reqstatus = ddi_get8(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->ReqStatus); - - tcontextp->retval = translate_error(reqstatus, detstatus, 0); - - mutex_enter(&tcontextp->bsadata->bsa_mutex); - tcontextp->replyflag |= REPLY_DONE; - cv_broadcast(&tcontextp->bsadata->reply_cv); - mutex_exit(&tcontextp->bsadata->bsa_mutex); -} - -/* - * The Media lock routine for BSA - */ - -static int -BsaMediaLock(bsa_data_t *bsadata) -{ - bsa_context_t *tcontextp; - ddi_acc_handle_t acc_handle; - i2o_msg_handle_t msg_handle; - i2o_bsa_media_lock_message_t *msgbuf; - int ret = DDI_SUCCESS; - - /* - * Allocate a message frame from IOP's inbound queue - * Sleep until the resource is available - */ - - if (i2o_msg_alloc(bsadata->iop, I2O_MSG_SLEEP, NULL, (void **)&msgbuf, - &msg_handle, &acc_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?BsaMediaLock: Frame buffer " - "resource not available\n"); - return (-1); - } - - /* - * Set up the Standard Message frame fields - */ - - setup_msghdr(I2O_BSA_MEDIA_LOCK, BsaMediaLock_reply, - &msgbuf->StdMessageFrame, acc_handle, 0x01, - bsadata->tid, 0, sizeof (i2o_bsa_media_lock_message_t)); - - /* Lock whatever currently mounted on the drive */ - ddi_put32(acc_handle, &msgbuf->MediaIdentifier, - I2O_BSA_MEDIA_ID_CURRENT_MOUNTED); - - /* - * Set the Transaction Context field (used for reply correlation) - */ - - tcontextp = (bsa_context_t *)kmem_zalloc(sizeof (bsa_context_t), - KM_SLEEP); - - tcontextp->bsadata = bsadata; - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContext, (unit64_t) - tcontextp); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContext, - (uint32_t)(uintptr_t)tcontextp); -#endif - - if (i2o_msg_send(bsadata->iop, msgbuf, msg_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?BsaMediaLock: i2o_msg_send failed "); - return (DDI_FAILURE); - } - - /* - * do a cv_wait here from reply - */ - mutex_enter(&bsadata->bsa_mutex); - while (!(tcontextp->replyflag & REPLY_DONE)) - cv_wait(&bsadata->reply_cv, &bsadata->bsa_mutex); - tcontextp->replyflag &= ~REPLY_DONE; - mutex_exit(&bsadata->bsa_mutex); - - ret = tcontextp->retval; - - kmem_free(tcontextp, sizeof (bsa_context_t)); - - return (ret); -} - -/* - * This is the reply routine for BsaMediaLock - */ - - -static void -BsaMediaLock_reply(void *msg, ddi_acc_handle_t acc_handle) -{ - - - bsa_context_t *tcontextp; - int detstatus, reqstatus; - - /* - * Get the Transacton Context field - */ -#if I2O_64BIT_CONTEXT - tcontextp = (bsa_context_t *)ddi_get64(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactiontContext)); -#else - tcontextp = (bsa_context_t *)(uintptr_t)ddi_get32(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactionContext)); -#endif - - /* - * Detailed status - */ - detstatus = ddi_get16(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->DetailedStatusCode); - - /* - * reply status - */ - reqstatus = ddi_get8(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->ReqStatus); - - tcontextp->retval = translate_error(reqstatus, detstatus, 0); - - mutex_enter(&tcontextp->bsadata->bsa_mutex); - tcontextp->replyflag |= REPLY_DONE; - cv_broadcast(&tcontextp->bsadata->reply_cv); - mutex_exit(&tcontextp->bsadata->bsa_mutex); -} - -/* - * Unlock the Media - */ -static int -BsaMediaUnlock(bsa_data_t *bsadata) -{ - bsa_context_t *tcontextp; - ddi_acc_handle_t acc_handle; - i2o_msg_handle_t msg_handle; - i2o_bsa_media_unlock_message_t *msgbuf; - int ret = DDI_SUCCESS; - - /* - * Allocate a message frame from IOP's inbound queue - * Sleep until the resource is available - */ - if (i2o_msg_alloc(bsadata->iop, I2O_MSG_SLEEP, NULL, (void **)&msgbuf, - &msg_handle, &acc_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?BsaMediaUnlock: Frame buffer " - "resource not available\n"); - return (-1); - } - - /* - * Set up the Standard Message frame fields - */ - setup_msghdr(I2O_BSA_MEDIA_UNLOCK, BsaMediaUnlock_reply, - &msgbuf->StdMessageFrame, acc_handle, 0x01, - bsadata->tid, 0, sizeof (i2o_bsa_media_unlock_message_t)); - - - /* - * Unlock whatever currently mounted on the drive - */ - ddi_put32(acc_handle, &msgbuf->MediaIdentifier, - I2O_BSA_MEDIA_ID_CURRENT_MOUNTED); - - /* - * Set the Transaction Context field (used for reply correlation) - */ - - tcontextp = (bsa_context_t *)kmem_zalloc(sizeof (bsa_context_t), - KM_SLEEP); - tcontextp->bsadata = bsadata; - -#if I2O_64BIT_CONTEXT - ddi_put64(acc_handle, &msgbuf->TransactionContext, (uint64_t) - tcontextp); -#else - ddi_put32(acc_handle, &msgbuf->TransactionContext, - (uint32_t)(uintptr_t)tcontextp); -#endif - - if (i2o_msg_send(bsadata->iop, msgbuf, msg_handle) == DDI_FAILURE) { - cmn_err(CE_CONT, "?BsaMediaUnlock: i2o_msg_send failed"); - return (DDI_FAILURE); - } - - /* - * do a cv_wait here from reply - */ - mutex_enter(&bsadata->bsa_mutex); - while (!(tcontextp->replyflag & REPLY_DONE)) - cv_wait(&bsadata->reply_cv, &bsadata->bsa_mutex); - tcontextp->replyflag &= ~REPLY_DONE; - mutex_exit(&bsadata->bsa_mutex); - - ret = tcontextp->retval; - - kmem_free(tcontextp, sizeof (bsa_context_t)); - - return (ret); -} - -/* - * This function is the reply function for Media unlock request - */ - -static void -BsaMediaUnlock_reply(void *msg, ddi_acc_handle_t acc_handle) -{ - - - bsa_context_t *tcontextp; - int detstatus, reqstatus; - - /* - * Get the Transacton Context field - */ -#if I2O_64BIT_CONTEXT - tcontextp = (bsa_context_t *)ddi_get64(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactiontContext)); -#else - tcontextp = (bsa_context_t *)(uintptr_t)ddi_get32(acc_handle, - &(((i2o_single_reply_message_frame_t *) - msg)->TransactionContext)); -#endif - /* - * Detailed status - */ - detstatus = ddi_get16(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->DetailedStatusCode); - - /* - * reply status - */ - reqstatus = ddi_get8(acc_handle, - &((i2o_single_reply_message_frame_t *) - msg)->ReqStatus); - - tcontextp->retval = translate_error(reqstatus, detstatus, 0); - - mutex_enter(&tcontextp->bsadata->bsa_mutex); - tcontextp->replyflag |= REPLY_DONE; - cv_broadcast(&tcontextp->bsadata->reply_cv); - mutex_exit(&tcontextp->bsadata->bsa_mutex); -} - - -/* - * This function releases the frame which was allocated by the OSM but was - * not used. This frame usually is freed by IOP after IOP sent the info to - * DDM or ISM. UtilNOP does not have a reply function. - */ -static void -UtilNOP(i2o_iop_handle_t handle, ddi_acc_handle_t acc_handle, - i2o_common_message_t *msgp, i2o_msg_handle_t msg_handle) -{ - /* send the UtilNop message to return the unused Message frame */ - msgp->StdMessageFrame.VersionOffset = I2O_VERSION_11; - msgp->StdMessageFrame.MsgFlags = 0; - ddi_put16(acc_handle, &msgp->StdMessageFrame.MessageSize, 3); - put_msg_Function(&msgp->StdMessageFrame, I2O_UTIL_NOP, acc_handle); - put_msg_InitiatorAddress(&msgp->StdMessageFrame, - I2O_HOST_TID, acc_handle); - put_msg_TargetAddress(&msgp->StdMessageFrame, - I2O_IOP_TID, acc_handle); - - (void) i2o_msg_send(handle, msgp, msg_handle); -} - -/* - * Pass the geom information - */ - -static void -geom_prep(struct dk_geom *dkg, struct bsa_unit *bsa_unit) -{ - bzero((caddr_t)dkg, sizeof (struct dk_geom)); - dkg->dkg_ncyl = bsa_unit->au_cyl; - dkg->dkg_nhead = bsa_unit->au_hd; - dkg->dkg_nsect = bsa_unit->au_sec; -} - -#define COPYOUT(a, b, c, f) \ - ddi_copyout((caddr_t)(a), (caddr_t)(b), sizeof (c), f) - -/* - * This function performs all the Block storage ioctls - */ - -/*ARGSUSED4*/ -static int -bsa_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p, - int *rval_p) -{ - - register struct bsa_unit *un; - auto long data[512 / (sizeof (long))]; - int instance; - struct bsa_data *bsadata; - struct dk_cinfo *info; - int i, status, ret; - - /* - * get instance number - */ - instance = UNIT(dev); - - if (!(bsadata = ddi_get_soft_state(bsa_soft, instance))) { - return (ENXIO); - } - -#ifdef BSA_DEBUG - { - char *cmdname; - - switch (cmd) { - case DKIOCINFO: cmdname = "DKIOCINFO "; break; - case DKIOCGGEOM: cmdname = "DKIOCGGEOM "; break; - case DKIOCGAPART: cmdname = "DKIOCGAPART "; break; - case DKIOCSAPART: cmdname = "DKIOCSAPART "; break; - case DKIOCGVTOC: cmdname = "DKIOCGVTOC "; break; - case DKIOCSVTOC: cmdname = "DKIOCSVTOC "; break; - case DKIOCG_VIRTGEOM: cmdname = "DKIOCG_VIRTGEOM "; break; - case DKIOCG_PHYGEOM: cmdname = "DKIOCG_PHYGEOM "; break; - case DKIOCEJECT: cmdname = "DKIOCEJECT *"; break; - case DKIOCSGEOM: cmdname = "DKIOCSGEOM *"; break; - case DKIOCSTATE: cmdname = "DKIOCSTATE *"; break; - case DKIOCADDBAD: cmdname = "DKIOCADDBAD *"; break; - case DKIOCGETDEF: cmdname = "DKIOCGETDEF *"; break; - case DKIOCPARTINFO: cmdname = "DKIOCPARTINFO *"; break; - case DIOCTL_RWCMD: cmdname = "DIOCTL_RWCMD "; break; - default: cmdname = "UNKNOWN *"; break; - } - cmn_err(CE_CONT, "?bsa_ioctl%d: cmd %x(%s) arg %x bsadata %x\n", - instance, cmd, cmdname, arg, bsadata); - } -#endif - - un = &bsadata->unitp; - bzero((caddr_t)data, sizeof (data)); - - switch (cmd) { - case DKIOCGGEOM: - case DKIOCSGEOM: - case DKIOCGAPART: - case DKIOCSAPART: - case DKIOCGVTOC: - case DKIOCSVTOC: - mutex_enter(&bsadata->lbl.mutex); - status = bsa_lbl_ioctl(dev, cmd, (int)arg, flag); - mutex_exit(&bsadata->lbl.mutex); - return (status); - } - - switch (cmd) { - case DKIOCSTATE: - { - enum dkio_state state; - mutex_enter(&bsadata->bsa_mutex); - if (bsadata->state & DKIO_EJECTED) - state = DKIO_EJECTED; - else - state = DKIO_INSERTED; - while (!(bsadata->flags & STATE_CHANGE)) - cv_wait(&bsadata->state_cv, - &bsadata->bsa_mutex); - mutex_exit(&bsadata->bsa_mutex); - - if (bsadata->state & DKIO_EJECTED) - state = DKIO_EJECTED; - else - state = DKIO_INSERTED; - - bsadata->flags &= ~STATE_CHANGE; - - if (ddi_copyout(&state, (caddr_t)arg, sizeof (int), - flag)) { - return (EFAULT); - } - } - break; - case DKIOCINFO: - - info = (struct dk_cinfo *)data; - /* - * Controller Information - */ - info->dki_ctype = un->au_type; - info->dki_cnum = ddi_get_instance(bsadata->dip); - (void) strcpy(info->dki_cname, - ddi_get_name(ddi_get_parent(bsadata->dip))); - /* - * Unit Information - */ - info->dki_unit = ddi_get_instance(bsadata->dip); - info->dki_slave = 0; - (void) strcpy(info->dki_dname, "card"); - info->dki_flags = 0; - info->dki_partition = LPART(dev); - - /* - * We can give the OSM's transfer rate, which is - * maxphys (maxphys/DEV_BSIZE). - */ - info->dki_maxtransfer = maxphys/DEV_BSIZE; - - /* - * We can't get from here to there yet - */ - info->dki_addr = 0; - info->dki_space = 0; - info->dki_prio = 0; - info->dki_vec = 0; - - if (COPYOUT(data, (uintptr_t)arg, struct dk_cinfo, flag)) - return (EFAULT); - break; - - case DKIOCG_VIRTGEOM: - case DKIOCG_PHYGEOM: - - { - struct dk_geom dkg; - - bzero((caddr_t)&dkg, sizeof (struct dk_geom)); - - dkg.dkg_ncyl = un->au_cyl; - dkg.dkg_acyl = un->au_acyl; - dkg.dkg_pcyl = un->au_cyl+un->au_acyl; - dkg.dkg_nhead = un->au_hd; - dkg.dkg_nsect = un->au_sec; - - if (ddi_copyout((caddr_t)&dkg, (caddr_t)arg, - sizeof (struct dk_geom), flag)) - return (EFAULT); - else - return (0); - } - - case DIOCTL_RWCMD: - { - struct dadkio_rwcmd rwcmd; - int status, rw; - - i = sizeof (rwcmd); - if (ddi_copyin((caddr_t)arg, (caddr_t)&rwcmd, i, flag)) - return (EFAULT); - - switch (rwcmd.cmd) { - case DADKIO_RWCMD_READ : - case DADKIO_RWCMD_WRITE: - rw = ((rwcmd.cmd == DADKIO_RWCMD_WRITE) ? - B_WRITE : B_READ); - status = bsa_buf_setup((void **)&rwcmd, dev, - ((flag & FKIOCTL) ? UIO_SYSSPACE : - UIO_USERSPACE), rw); - return (status); - default: - return (EINVAL); - } - } - - case DKIOCADDBAD: - break; - - /* - * Generic lock - */ - case DKIOCLOCK: - return (BsaMediaLock(bsadata)); - - /* - * Generic unlock - */ - case DKIOCUNLOCK: - return (BsaMediaUnlock(bsadata)); - - case DKIOCREMOVABLE: - { - int i; - - /* - * Get the information from Unit structure. - * The information was gathered at attach time - * through UtilParamsGet() - */ - - i = (un->au_devicecapability & - I2O_BSA_DEV_CAP_REMOVABLE_MEDIA); - - if (ddi_copyout((caddr_t)&i, (caddr_t)arg, - sizeof (int), flag)) { - return (EFAULT); - - } - return (0); - } - - case DKIOCEJECT: - case CDROMEJECT: - - /* - * If it is not a removable media or device this ioctl - * does not exist. - */ - - if (!(un->au_devicecapability & - I2O_BSA_DEV_CAP_REMOVABLE_MEDIA || - un->au_devicecapability & - I2O_BSA_DEV_CAP_REMOVEABLE_DEVICE)) - - return (ENOSYS); - /* - * First need to unlock before eject - */ - - if (ret = (BsaMediaUnlock(bsadata))) - return (ret); - - return (BsaMediaEject(bsadata)); - - - case HDKIOCSCMD: - case HDKIOCGDIAG: - break; - default: - return (ENOTTY); - } - return (0); -} - - -/* - * This function contains all the ioctls for labeling - */ - -static int -bsa_lbl_ioctl(dev_t dev, int cmd, int arg, int flag) -{ - auto long data[512 / (sizeof (long))]; - int instance; - struct bsa_data *bsadata; - int i; - - /* - * get instance number - */ - instance = UNIT(dev); - - - if (!(bsadata = ddi_get_soft_state(bsa_soft, instance))) { - return (ENXIO); - } - /* - * For future hot plugging make sure the device exist - */ - - bzero((caddr_t)data, sizeof (data)); - - switch (cmd) { - case DKIOCGGEOM: - case DKIOCGAPART: - case DKIOCGVTOC: - if (update_vtoc(bsadata, dev)) - return (EFAULT); - } - - switch (cmd) { - case DKIOCGGEOM: - { - struct dk_geom up; - - dsklbl_dgtoug(&up, &bsadata->lbl.ondsklbl); - if (COPYOUT(&up, (uintptr_t)arg, struct dk_geom, - flag)) - return (EFAULT); - break; - } - - case DKIOCSGEOM: - i = sizeof (struct dk_geom); - if (ddi_copyin((caddr_t)(uintptr_t)arg, (caddr_t)data, i, flag)) - return (EFAULT); - dsklbl_ugtodg((struct dk_geom *)data, &bsadata->lbl.ondsklbl); - break; - - case DKIOCGAPART: - /* - * Return the map for all logical partitions. - */ - i = NDKMAP * sizeof (struct dk_map); - if (ddi_copyout((caddr_t)bsadata->lbl.un_map, - (caddr_t)(uintptr_t)arg, i, flag)) { - return (EFAULT); - } - break; - - case DKIOCSAPART: - /* - * Set the map for all logical partitions. - */ - i = NDKMAP * sizeof (struct dk_map); - if (ddi_copyin((caddr_t)(uintptr_t)arg, (caddr_t)data, i, flag)) - return (EFAULT); - bcopy((caddr_t)data, (caddr_t)bsadata->lbl.un_map, i); - break; - - case DKIOCGVTOC: - i = sizeof (struct vtoc); - dsklbl_ondsklabel_to_vtoc(&bsadata->lbl, (struct vtoc *)data); - if (ddi_copyout((caddr_t)data, (caddr_t)(uintptr_t)arg, i, - flag)) - return (EFAULT); - else - return (0); - case DKIOCSVTOC: - i = sizeof (struct vtoc); - if (ddi_copyin((caddr_t)(uintptr_t)arg, (caddr_t)data, i, - flag)) - return (EFAULT); - - if (write_dskvtoc(bsadata, dev, &bsadata->lbl, - (struct vtoc *)data, &bsa_cb_ops)) { - return (EFAULT); - } - break; - } - return (0); -} - -static int bsa_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, - int mod_flags, char *name, caddr_t valuep, int *lengthp) -{ - int instance = ddi_get_instance(dip); - struct bsa_data *bsadata; - uint64_t nblocks64; - - /* - * Our dynamic properties are all device specific and size oriented. - * Requests issued under conditions where size is valid are passed - * to ddi_prop_op_nblocks with the size information, otherwise the - * request is passed to ddi_prop_op. Size depends on valid geometry. - */ - bsadata = ddi_get_soft_state(bsa_soft, instance); - if ((dev == DDI_DEV_T_ANY) || (bsadata == NULL) || - !(bsadata->lbl.pmap[LPART(dev)].p_flag & V_INVALID)) { - return (ddi_prop_op(dev, dip, prop_op, mod_flags, - name, valuep, lengthp)); - } else { - /* get nblocks value */ - nblocks64 = (ulong_t)bsadata->lbl.pmap[LPART(dev)].p_size; - - return (ddi_prop_op_nblocks(dev, dip, prop_op, mod_flags, - name, valuep, lengthp, nblocks64)); - } -} - -/* - * Setup the capacity and type information - */ - -static int -bsa_setup(struct bsa_data *bsadata) -{ - - struct bsa_unit *bsa_unitp; - - bsa_unitp = &bsadata->unitp; - - /* - * Use 6-43 GroupNumber 0000h and GroupType SCALAR and Name: DEVICE - * INFORMATION. Basically need DeviceType and BlockSize and - * DeviceCapacity. Probably want to setup the SGL here and put hte - * parameters that want to send. If provide one SGL buffer the - * result will be in the payload reply. Decide what you want to do - */ - - - if (UtilParamsGet(bsadata)) - return (DDI_FAILURE); - - /* - * bsa_setup will be called from attach and whenver receive an event - * for change of device parameres - */ - - mutex_enter(&bsadata->bsa_mutex); - - if (bsa_unitp->au_type == I2O_BSA_DEVICE_TYPE_DIRECT) - bsa_unitp->au_type = DKC_DIRECT; - else if (bsa_unitp->au_type == I2O_BSA_DEVICE_TYPE_CDROM) - bsa_unitp->au_type = DKC_CDROM; - else { - /* - * In dadk has DDI_PROB_FAILURE These are WORM and OPTICAL - * that we do not have support under Solaris. We may not - * need to do any extra stuff. that case DKC_DIRECT should - * work. - */ - return (DDI_FAILURE); - } - - if (bsa_unitp->au_capacity > 0) - cap_translation(bsa_unitp->au_capacity, &(bsa_unitp->au_cyl), - &(bsa_unitp->au_hd), &(bsa_unitp->au_sec)); - else - return (DDI_FAILURE); - - bsa_unitp->au_acyl = 2; - - mutex_exit(&bsadata->bsa_mutex); - - mutex_enter(&bsadata->lbl.mutex); - bsadata->lbl.geomread = 1; - mutex_exit(&bsadata->lbl.mutex); - - DEBUGF(I2O_DEBUG_DIO, (CE_CONT, "?bsa_setup:targ = %d cyl = %d" - "acyl = %d head = %d" - " sec = %d\n", - bsadata->tid, - bsa_unitp->au_cyl, - bsa_unitp->au_acyl, - bsa_unitp->au_hd, - bsa_unitp->au_sec)); - return (DDI_SUCCESS); - -} - -/* - * The following is according to Intel's int13 translation for I2O. - * (This needs more investigation). - */ - - -#define MB (63 * 16 * 512 * 1023LL) /* 528MB */ -#define CAPACITY0 (63 * 32 * 512 * 1023LL) /* (1*GB) */ -#define CAPACITY1 (63 * 64 * 512 * 1023ULL) /* (2.1*GB) */ -#define CAPACITY2 (63 * 128 * 512 * 1023ULL) /* (4.2*GB) */ -#define CAPACITY3 (63 * 255 * 512 * 1023ULL) /* (8.4*GB) */ -#define FIXED_SECSIZE 512 -#define FIXED_SECNUM 63 -#define FIXED_MAXHEAD 255 - -static void -cap_translation(uint64_t capacity, int *cyls, int *hds, int *secs) -{ - - - *secs = FIXED_SECNUM; - *hds = 16; - - -/* */ -/* if (capacity <= (MB)) */ -/* *hds = 16; */ -/* else if (capacity <= (CAPACITY0)) */ -/* *hds *= 2; */ -/* else if (capacity <= (CAPACITY1)) */ -/* *hds *= 4; */ -/* else if (capacity <= (CAPACITY2)) */ -/* *hds *= 8; */ -/* else if (capacity <= (CAPACITY3)) */ -/* *hds = FIXED_MAXHEAD; */ -/* else { (capacity > CAPACITY3) */ -/* cmn_err(CE_WARN, "?cap_translation: The drive is greater" */ -/* "than 8.4 GB. int13 only support up to 8.4 GB \n"); */ -/* *hds = FIXED_MAXHEAD; */ -/* } */ - - - - *cyls = (capacity/(*secs * *hds * FIXED_SECSIZE)); - - DEBUGF(I2O_DEBUG_DIO, (CE_CONT, "?translation:capacity =%lld cyl = %d" - "head = %d" - " sec = %d\n", - capacity, - *cyls, - *hds, - *secs)); - -} - - -/* - * Setup the read write buffer - */ - -static int -bsa_buf_setup(void **cmdp, dev_t dev, enum uio_seg dataspace, int rw) -{ - register struct dadkio_rwcmd *rwcmdp = (struct dadkio_rwcmd *)cmdp; - register struct buf *bp; - int status; - auto struct iovec aiov; - auto struct uio auio; - register struct uio *uio = &auio; - - bp = getrbuf(KM_SLEEP); - - bp->b_back = (struct buf *)rwcmdp; /* ioctl packet */ - bp->b_private = (void *)0xBEE; - - bzero((caddr_t)&auio, sizeof (struct uio)); - bzero((caddr_t)&aiov, sizeof (struct iovec)); - aiov.iov_base = rwcmdp->bufaddr; - aiov.iov_len = rwcmdp->buflen; - uio->uio_iov = &aiov; - - uio->uio_iovcnt = 1; - uio->uio_resid = rwcmdp->buflen; - uio->uio_segflg = dataspace; - - /* - * Let physio do the rest... - */ - status = physio(bsa_strategy, bp, dev, rw, minphys, uio); - - freerbuf(bp); - return (status); -} diff --git a/usr/src/uts/common/io/i2o/i2o_bs.conf b/usr/src/uts/common/io/i2o/i2o_bs.conf deleted file mode 100644 index 9445c9b6ba..0000000000 --- a/usr/src/uts/common/io/i2o/i2o_bs.conf +++ /dev/null @@ -1,29 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright (c) 1998 by Sun Microsystems, Inc. -# All rights reserved. -# - -#pragma ident "%Z%%M% %I% %E% SMI" - -name="i2o_bs" class="i2o"; diff --git a/usr/src/uts/common/io/i2o/i2o_bs.h b/usr/src/uts/common/io/i2o/i2o_bs.h deleted file mode 100644 index 73b26a553f..0000000000 --- a/usr/src/uts/common/io/i2o/i2o_bs.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998-1999 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _I2O_BS_H -#define _I2O_BS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ROUNDUP(a, n) (((a) + ((n) - 1)) & ~((n) - 1)) -#define UNIT(dev) (getminor((dev)) >> UNITSHF) -#define BSA_SETMINOR(skt, part) ((skt << UNITSHF) | (part)) - -#if defined(_SUNOS_VTOC_16) -#define UNITSHF 6 -#define MAXPART (1 << UNITSHF) -#define LPART(dev) (getminor((dev)) & (MAXPART - 1)) -#elif defined(_SUNOS_VTOC_8) -#define UNITSHF 3 -#define PART_MASK 7 -#define LPART(dev) (getminor((dev)) & PART_MASK) -#else -#error No VTOC format defined. -#endif - - -#define V_INVALID 0x80 -#define FDISK_OFFSET MAX_SLICES -#if defined(_SUNOS_VTOC_16) -#define MAX_SLICES 16 -#define VTOC_OFFSET 1 -#elif defined(_SUNOS_VTOC_8) -#define VTOC_OFFSET 0 -#define MAX_SLICES 8 -#else -#error No VTOC format defined. -#endif -#define USLICE_WHOLE 2 -#define FPART_WHOLE 0 -#define NUM_PARTS (MAX_SLICES + FD_NUMPART + 1) - -#define REPLY_DONE 1 /* The reply is done */ -#define STATE_CHANGE 0x0001 /* STATE has changned */ -#define CLAIMED 0x0002 /* device is claimed */ -#define I2O_BSA_NAME "i2o_bs" - - -#define ISCD(p) ((p)->unitp.au_type == DKC_CDROM) -#define ISREMOVABLE(p) \ - ((p)->unitp.au_devicecapability & I2O_BSA_DEV_CAP_REMOVABLE_MEDIA) - -#define ISWRITEPROTECT(p) \ - ((p)->unitp.au_devicecapability & I2O_BSA_DEV_CAP_READ_ONLY) - - - -typedef struct dsk_label { - struct dk_label ondsklbl; - struct partition pmap[NUM_PARTS]; - struct dk_map un_map[NDKMAP]; /* logical partitions */ - int uidx; - int fdiskpresent; - int vtocread; - int geomread; - kmutex_t mutex; - -} dsk_label_t; - - -struct bsa_unit { - int au_cyl; - int au_acyl; - int au_hd; - int au_sec; - long au_blksize; - short au_bytes_per_block; - int au_type; - uint64_t au_capacity; - long au_devicecapability; -}; - -typedef struct bsa_data { - int flags; /* misc state info */ - int tid; /* local targer id ( From LCT) */ - int instance; /* instantiation of ourselves */ - int open_flag; /* open flag used for rem media */ - unsigned long state; /* State of removable media */ - struct buf *crashbuf; /* used when dumping to root device */ - i2o_iop_handle_t iop; /* IOP access handle */ - dev_info_t *dip; /* pointer to our own device node */ - dsk_label_t lbl; /* per targer label information */ - struct bsa_unit unitp; /* phsyical characteristics */ - kcondvar_t reply_cv; /* conditional variable */ - kcondvar_t rwreply_cv; /* read/write cond variable */ - kcondvar_t state_cv; /* state cond variable */ - kmutex_t bsa_mutex; /* bs mutex */ -} bsa_data_t; - - -typedef struct bsa_context { - struct bsa_data *bsadata; - int deterror; /* detail error */ - int retval; /* return value from reply */ - int replyflag; /* reply flag */ - int rwreplyflag; /* reply flag */ - ddi_dma_handle_t dma_handle; /* DMA Handle */ - ddi_acc_handle_t acc_handle; /* DMA Handle */ - ddi_dma_handle_t dma_sghandle; /* DMA Handle */ - ddi_acc_handle_t acc_sghandle; /* DMA Handle */ - ddi_dma_handle_t dma_sg2handle; /* DMA Handle */ - ddi_acc_handle_t acc_sg2handle; /* DMA Handle */ -} bsa_context_t; - -typedef struct i2o_common_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_common_message_t; - -typedef struct i2o_reassign_addr_message { - uint32_t ByteCount; - uint64_t LogicalByteAddress; -} i2o_reassign_addr_message_t; - - - -#ifdef __cplusplus -} -#endif - -#endif /* _I2O_BS_H */ diff --git a/usr/src/uts/common/io/i2o/i2o_impl.h b/usr/src/uts/common/io/i2o/i2o_impl.h deleted file mode 100644 index db06469cb7..0000000000 --- a/usr/src/uts/common/io/i2o/i2o_impl.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _I2O_IMPL_H -#define _I2O_IMPL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/dditypes.h> -#include <sys/i2o/i2omsg.h> -#include <sys/i2o/i2outil.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef DEBUG -#define I2O_DEBUG -#endif - -/* - * ***************************************************************** - * Definitions used in the implementation of I2O nexus driver and - * I2O Message module. These are implementation specific definitions. - * ***************************************************************** - */ - -/* - * i2o_msg_trans structure: - * - * version I2O_MSG_TRANS_VER0 (version of this structure). - * - * iop_base_addr Base (virtual) address of device memory where - * inbound message frames are allocated. The MFA - * read from the inbound FIFO is an offset from - * this base address. - * - * iop_inbound_fifo_paddr - * Inbound Fifo port address (physical). - * - * acc_handle DDI access handle to access any message frame - * from the inbound queue. - * - * nexus_handle I2O Nexus handle argument to nexus transport - * functions. - * - * iblock_cookie Cookie needed for mutex_init(). - * - * i2o_trans_msg_alloc - * Allocates a message frame from the inbound - * queue. It reads the inbound FIFO register - * and returns the MFA. - * - * i2o_trans_msg_send - * Write the MFA to the inbound queue of the IOP. - * - * i2o_trans_msg_recv - * Reads the outbound queue for the reply - * messages and returns the MFA. The MFA is - * -1 if there are no reply messages. - * - * i2o_trans_msg_freebuf - * Writes the MFA into the outbound queue. - * - * i2o_trans_disable_intr - * Disables the IOP hardware interrupts. - * - * i2o_trans_enable_intr - * Enables the IOP hardware interrupts. - */ - -#define I2O_MSG_TRANS_VER0 0 -#define I2O_MSG_TRANS_VER I2O_MSG_TRANS_VER0 - -typedef void *i2o_nexus_handle_t; - -typedef struct i2o_msg_trans { - int version; - caddr_t iop_base_addr; - uint32_t iop_inbound_fifo_paddr; - ddi_acc_handle_t acc_handle; - i2o_nexus_handle_t nexus_handle; - ddi_iblock_cookie_t iblock_cookie; - uint_t (* i2o_trans_msg_alloc)(i2o_nexus_handle_t - nexus_handle); - int (* i2o_trans_msg_send)(i2o_nexus_handle_t nexus_handle, - uint_t mfa); - uint_t (* i2o_trans_msg_recv)(i2o_nexus_handle_t nexus_handle); - void (* i2o_trans_msg_freebuf)(i2o_nexus_handle_t - nexus_handle, uint_t mfa); - void (* i2o_trans_disable_intr)(i2o_nexus_handle_t - nexus_handle); - void (* i2o_trans_enable_intr)(i2o_nexus_handle_t - nexus_handle); -} i2o_msg_trans_t; - - -i2o_iop_handle_t i2o_msg_iop_init(dev_info_t *rdip, i2o_msg_trans_t *trans); -void i2o_msg_process_reply_queue(i2o_iop_handle_t iop); -int i2o_msg_iop_uninit(i2o_iop_handle_t *iop); -void i2o_msg_get_lct_info(i2o_iop_handle_t *, i2o_lct_t **, ddi_acc_handle_t *); - -#ifdef __cplusplus -} -#endif - -#endif /* _I2O_IMPL_H */ diff --git a/usr/src/uts/common/io/i2o/i2o_msg.c b/usr/src/uts/common/io/i2o/i2o_msg.c deleted file mode 100644 index 4066433e75..0000000000 --- a/usr/src/uts/common/io/i2o/i2o_msg.c +++ /dev/null @@ -1,3307 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * I2O Message module, which implements OSM interfaces to provides - * transport functionality for the OSMs. It depends on the I2O nexus - * driver for bus specific transport mechanisms. - * - * Note: The current implementation assumes only 32bit virtual - * addresses and 32bit context fields in I2O messages. - */ - -#include <sys/types.h> -#include <sys/cmn_err.h> -#include <sys/conf.h> -#include <sys/debug.h> -#include <sys/modctl.h> -#include <sys/errno.h> -#include <sys/ddidmareq.h> -#include <sys/ddi_impldefs.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/pci.h> -#include <sys/avintr.h> -#include <sys/bustypes.h> -#include <sys/kmem.h> -#include <sys/archsystm.h> -#include <sys/disp.h> - -#include "i2o_impl.h" -#include <sys/i2o/i2oexec.h> - -#ifndef I2O_BOOT_SUPPORT -#include <sys/sunndi.h> - -char _depends_on[] = "misc/busra"; -#endif - -/* - * ************************************************************************ - * *** Implementation specific data structures/definitions. *** - * ************************************************************************ - */ - -/* - * Implementation of i2o_iop_handle_t data structure. - * - * dip devinfo node pointer of the I2O device - * tid IOP assigned TID for this device. - * iop pointer to iop_instance_t data structure. - */ - -typedef struct i2o_iop_impl_hdl { - dev_info_t *dip; - uint32_t tid; - struct iop_instance *iop; -} i2o_iop_impl_hdl_t; - -/* - * Implementation of i2o_msg_handle_t data structure. - * - * next pointer to the next handle (used when the requests - * are queued up) - * dma_handle DMA handle associated with this message buffer - * msgp pointer to the message frame. - * acc_hdl DDI access handle for this message frame. - */ - -typedef struct i2o_msg_impl_hdl { - struct i2o_msg_impl_hdl *next; - ddi_dma_handle_t dma_handle; - ddi_acc_handle_t acc_hdl; - void *msgp; -} i2o_msg_impl_hdl_t; - -/* - * Per IOP instance data structure maintained by the I2O Message - * module. - * - * Locks used: - * iop_ib_mutex Used to serialize access to the inbound message - * queue and to protect send_queue_* fields. - * - * iop_ob_mutex Used to serialize access to the outbound message - * queue. - */ -typedef struct iop_instance { - - struct iop_instance *next; - uint_t iop_id; - volatile int iop_flags; - i2o_msg_trans_t *nexus_trans; - dev_info_t *dip; - kmutex_t iop_ib_mutex; - kmutex_t iop_ob_mutex; - uint32_t event_mask; - uint_t ib_msg_frame_size; - - /* IOP Status Block structure */ - struct { - i2o_exec_status_get_reply_t *bufp; - ddi_acc_handle_t acc_hdl; - ddi_dma_handle_t dma_handle; - } status; - - /* Logical Configuration Table (LCT) */ - struct { - i2o_lct_t *bufp; - ddi_acc_handle_t acc_hdl; - size_t size; - ddi_dma_handle_t dma_handle; - kmutex_t lct_mutex; - } lct; - - /* Hardware Resource Table (HRT) */ - struct { - i2o_hrt_t *bufp; - ddi_acc_handle_t acc_hdl; - uint_t size; - ddi_dma_handle_t dma_handle; - } hrt; - - /* outbound message queue */ - struct { - caddr_t base_addr; - uint_t base_paddr; - ddi_acc_handle_t acc_hdl; - uint_t nframes; - uint_t framesize; - ddi_dma_handle_t dma_handle; - } ob_msg_queue; - - /* private memory/io space allocated for IOP hw configuration */ - struct { - uint_t mem_base; - uint_t mem_size; - uint_t io_base; - uint_t io_size; - } hw_config; - - /* System Table Entry for this IOP */ - struct { - ddi_dma_handle_t dma_handle; - i2o_iop_entry_t *bufp; - ddi_acc_handle_t acc_hdl; - } systab; - - /* OSM registration book keeping */ - struct { - i2o_iop_impl_hdl_t *iop_handle_tab; - uint_t max_tid; - kmutex_t osm_mutex; - } osm_registry; - - /* - * i2o_send_msg() queue information. The fields send_queue_head - * and send_queue_tail are protected under iop_ib_mutex. - */ - i2o_msg_impl_hdl_t *send_queue_head; - i2o_msg_impl_hdl_t *send_queue_tail; - ulong_t send_queue_count; - kcondvar_t send_queue_cv; -} iop_instance_t; - -/* common transaction context structure */ - -typedef struct tcontext { - iop_instance_t *iop; - kmutex_t cv_mutex; - kcondvar_t cv; - int status; - int done_flag; -} tcontext_t; - -/* definitions for iop_flags values */ -#define IOP_IS_IN_INIT 1 /* IOP is being initialized */ -#define IOP_IS_ONLINE 2 /* IOP is initilized */ -#define IOP_IS_IN_UNINIT 4 /* IOP is being uninitialized */ -#define IOP_SEND_QUEUE_PROC_RUNNING 8 /* i2o_msg_send_proc() running */ - -/* - * DMA attribute structure for I2O Spec version 1.5. - * - * (Note: Specifies sg list length to 1 to get contiguous memory) - */ -static ddi_dma_attr_t dma_attr_contig = { - DMA_ATTR_VERSION, /* version number */ - (uint64_t)0, /* low DMA address range */ - (uint64_t)0xFFFFFFFF, /* high DMA address range */ - (uint64_t)0x00FFFFFF, /* DMA counter register */ - 1, /* DMA address alignment */ - 1, /* DMA burstsizes */ - 1, /* min effective DMA size */ - (uint64_t)0xFFFFFFFF, /* max DMA xfer size */ - (uint64_t)0xFFFFFFFF, /* segment boundary */ - 0x1, /* s/g length */ - 1, /* granularity of device */ - 0 /* Bus specific DMA flags */ -}; - -/* - * Device attribute structure for I2O version 1.5. - * - * I2O data structures (whether it is in IOP's memory or host memory) - * are in Little Endian format. - */ -static ddi_device_acc_attr_t i2o_dev_acc_attr = { - DDI_DEVICE_ATTR_V0, - DDI_STRUCTURE_LE_ACC, /* devacc_attr_endian_flags for LE access */ - DDI_STRICTORDER_ACC /* devacc_attr_dataorder */ -}; - -/* Function prototypes for local functions */ - -static int i2o_get_iop_status(iop_instance_t *iop); -static int i2o_init_outbound_queue(iop_instance_t *iop); -static int i2o_get_hrt(iop_instance_t *iop); -static int i2o_create_systab(iop_instance_t *iop); -static int i2o_send_exec_enable(iop_instance_t *iop); -static int i2o_get_lct(iop_instance_t *iop); -static int i2o_iop_event_register(iop_instance_t *iop); -static void i2o_msg_iop_event_reply(void *p, ddi_acc_handle_t acc_hdl); -static void i2o_msg_common_reply(void *p, ddi_acc_handle_t acc_hdl); -static int i2o_send_exec_iop_reset(iop_instance_t *iop); -static void i2o_msg_send_proc(iop_instance_t *iop); - -static void i2o_return_mem(dev_info_t *, uint_t, uint_t); -static uint_t i2o_get_mem(dev_info_t *, uint_t, uint_t *); -static uint_t i2o_get_io(dev_info_t *, uint_t, uint_t *); -static void i2o_return_io(dev_info_t *, uint_t, uint_t); - -#ifdef I2O_DEBUG -/* function prototypes for debug functions */ -static void dump_reply_message(iop_instance_t *iop, - i2o_single_reply_message_frame_t *rmp); -static void dump_hrt(iop_instance_t *iop); -static void dump_lct(iop_instance_t *iop); -static void dump_iop_status_buf(iop_instance_t *iop); -static void dump_message(uint32_t *mp, char *name); -#endif - -/* - * Local Data definitions. - * - * niop - * number of active IOPs initialized to OP state. - * - * next_iop_id - * Counter to assign unique ID (IOP_ID) to the next IOP that - * gets initialized by the i2o nexus. - * - * ioplist - * pointer to the linked list of IOP data structures (i.e iop_instance - * structures) that are initilized. - * - * iop_reset_time_delay_in_ticks - * This is the time delay to get a valid mfa from the inbound freelist - * after doing ExecIopReset. This delay really depends on the platform - * specific hardware. Here we are using 2 seconds and this seems to - * work fine for the Madrona platform. - */ - -#define BASE_IOP_ID 2 /* IOP IDs 0 and 1 are reserved */ - -static uint_t niop = 0; -static uint_t next_iop_id = BASE_IOP_ID; -static iop_instance_t *ioplist; -int iop_reset_time_delay_in_ticks = 200; - -kmutex_t i2o_mutex; /* protects common data like ioplist, etc. */ - -/* - * Debug flag definitions. - */ -#define I2O_DEBUG_DEBUG 0x80000000 /* general debugging info */ -#define I2O_DEBUG_MSG 0x00000001 /* dump message frames */ -#define I2O_DEBUG_HRT 0x40000000 /* dump HRT table */ -#define I2O_DEBUG_STATUS 0x20000000 /* dump IOP Status block */ -#define I2O_DEBUG_LCT 0x10000000 /* dump LCT table */ -#define I2O_DEBUG_IOP_PARAMS 0x08000000 /* dump IOP parameters */ - -#ifdef I2O_DEBUG -int i2o_debug = I2O_DEBUG_LCT; - -#define DEBUGF(flag, args) \ - { if (i2o_debug & (flag)) cmn_err args; } -#else -#define DEBUGF(level, args) /* nothing */ -#endif - -#define SUCCESS 1 -#define FAILURE 0 - -/* - * Module linkage information for the kernel. - */ -extern struct mod_ops mod_miscops; -static struct modlmisc modlmisc = { - &mod_miscops, - "I2O Message Module version 1.5", -}; - - -static struct modlinkage modlinkage = { - MODREV_1, - &modlmisc, - NULL -}; - -int -_init(void) -{ - int error; - - mutex_init(&i2o_mutex, NULL, MUTEX_DRIVER, NULL); - - if ((error = mod_install(&modlinkage)) != 0) - mutex_destroy(&i2o_mutex); - - return (error); -} - -int -_fini(void) -{ - int error; - - if ((error = mod_remove(&modlinkage)) == 0) - mutex_destroy(&i2o_mutex); - - return (error); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - - -/* - * Utility macros to initialize message structures. - */ -/* initialize standard message header */ -#define init_std_msghdr(iop, mp, ver_off, msg_flags, msg_size, func) \ - { \ - (mp)->VersionOffset = (ver_off) | I2O_VERSION_11; \ - (mp)->MsgFlags = (msg_flags); \ - ddi_put16((iop)->nexus_trans->acc_handle, \ - &(mp)->MessageSize, (msg_size) >> 2); \ - put_msg_Function((mp), (func), (iop)->nexus_trans->acc_hdl); \ - put_msg_InitiatorAddress((mp), I2O_HOST_TID, \ - (iop)->nexus_trans->acc_hdl); \ - put_msg_TargetAddress((mp), I2O_IOP_TID, \ - (iop)->nexus_trans->acc_hdl); \ - } - -/* initialize standard SGL Simple Element structure */ -#define init_sgl_simple_ele(iop, sgl, flags, count, addr) \ - { \ - put_flags_count_Flags(&(sgl)->FlagsCount, \ - (flags) | I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT, \ - (iop)->nexus_trans->acc_hdl); \ - ddi_put32((iop)->nexus_trans->acc_handle, \ - &(sgl)->PhysicalAddress, (uint_t)(addr)); \ - put_flags_count_Count(&(sgl)->FlagsCount, (count), \ - (iop)->nexus_trans->acc_hdl); \ - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, "SGL(0x%p): %x %x", \ - (void *)sgl, ((uint32_t *)sgl)[0], ((uint32_t *)sgl)[1])); \ - } - -/* - * ************************************************************************ - * Tunable parameters/properties. - * ob_msg_framesize_default - * Default frame size for Outbound Message queue. The minimum - * size is 64 bytes. It should be multiple of 4. - * ob_msg_queue_length_default - * Default size (i.e #of MFAs) in the Outbound Queue. The - * minimum is 16. - * ************************************************************************ - */ -int ob_msg_framesize_default = 128; -int ob_msg_queue_length_default = 32; - -/* - * ************************************************************************ - * Transport utility functions/macros used in IOP initialization. - * ************************************************************************ - */ - -#define iop_msg_send(iop, msgp) \ - (* iop->nexus_trans->i2o_trans_msg_send) \ - (iop->nexus_trans->nexus_handle, \ - (caddr_t)(msgp) - iop->nexus_trans->iop_base_addr) - - -#define iop_msg_free(iop, rmp) \ - (* iop->nexus_trans->i2o_trans_msg_freebuf) \ - (iop->nexus_trans->nexus_handle, \ - ((caddr_t)(rmp) - iop->ob_msg_queue.base_addr) + \ - iop->ob_msg_queue.base_paddr) - -static i2o_single_reply_message_frame_t * -iop_poll_reply_msg(iop_instance_t *iop) -{ - uint_t mfa; - uint_t ticks = 10000; /* time out polling for 10 seconds */ - - mfa = (* iop->nexus_trans->i2o_trans_msg_recv) - (iop->nexus_trans->nexus_handle); - - while (mfa == (uint_t)0xFFFFFFFF) { - delay(1); - mfa = (* iop->nexus_trans->i2o_trans_msg_recv) - (iop->nexus_trans->nexus_handle); - if (--ticks == 0) { - DEBUGF(I2O_DEBUG_DEBUG, - (CE_CONT, "iop_poll_reply_msg: timed out")); - return (NULL); /* time out - possible hang? */ - } - } - - return ((i2o_single_reply_message_frame_t *) - ((mfa - iop->ob_msg_queue.base_paddr) + - iop->ob_msg_queue.base_addr)); -} - -void * -iop_msg_alloc(iop_instance_t *iop) -{ - uint32_t mfa; - - mfa = (* iop->nexus_trans->i2o_trans_msg_alloc) - (iop->nexus_trans->nexus_handle); - - /* - * If we don't have a valid frame then wait for a while and - * try again. This may be necessary at the beginning if - * the IOP is in the INITIALIZATION state. - */ - if (mfa == (uint_t)0xFFFFFFFF) { - delay(100); - mfa = (* iop->nexus_trans->i2o_trans_msg_alloc) - (iop->nexus_trans->nexus_handle); - } - - return (mfa == (uint_t)0xFFFFFFFF ? NULL : - (void *)(mfa + iop->nexus_trans->iop_base_addr)); -} - - -/* - * ************************************************************************ - * ********* Private interfaces used by the I2O Nexus driver. *********** - * ************************************************************************ - */ - -/* - * i2o_msg_iop_init() - * - * Called from the attach(9E) function in the i2o nexus driver. - * Initializes the IOP to the OPERATIONAL state. Returns an access - * handle (i.e i2o_iop_handle_t) for successful initialization, - * otherwise it returns NULL. - * - * Assumption(s): - * 1. The IOP interrupts are not enabled when this function is - * called. The caller (i.e attach(9E)) enables the IOP interrupts - * upon the successful return from this function. - * 2. It is assumed that the I2O nexus driver will create the - * devinfo nodes for the I2O devices if necessary. i.e the - * caller of this function will create the devinfo tree - * based on the LCT/HRT information if the boot firmware hasn't - * already created it. - */ - -i2o_iop_handle_t -i2o_msg_iop_init(dev_info_t *dip, i2o_msg_trans_t *trans) -{ - iop_instance_t *iop; - uint32_t priv_mem_size; - uint32_t priv_io_size; - i2o_iop_impl_hdl_t *hdl; - i2o_lct_entry_t *lct_entp; - uint_t lct_entries; - int i; - int reset_done = 0; /* only one IOP_RESET operation */ - int init_time; - - /* - * Allocate an iop instance data. - */ - iop = (iop_instance_t *)kmem_zalloc(sizeof (iop_instance_t), KM_SLEEP); - - mutex_enter(&i2o_mutex); - - iop->dip = dip; - iop->iop_flags |= IOP_IS_IN_INIT; /* IOP is being initialized */ - iop->nexus_trans = trans; - - niop++; - iop->iop_id = next_iop_id++; /* assign a unique ID to this IOP */ - - mutex_init(&iop->iop_ib_mutex, NULL, MUTEX_DRIVER, - (void *)iop->nexus_trans->iblock_cookie); - mutex_init(&iop->iop_ob_mutex, NULL, MUTEX_DRIVER, - (void *)iop->nexus_trans->iblock_cookie); - mutex_init(&iop->osm_registry.osm_mutex, NULL, MUTEX_DRIVER, - (void *)iop->nexus_trans->iblock_cookie); - mutex_init(&iop->lct.lct_mutex, NULL, MUTEX_DRIVER, - (void *)iop->nexus_trans->iblock_cookie); - - /* - * ************************************************************** - * Step 1: Get the IOP status block by sending ExecStatusGet - * message. - * - * NOTE: Normally we expect IOP to be in 'RESET' state or 'OP' - * state. Any other state is really doubtful! - * ************************************************************** - */ - - /* - * We give 5 minutes for IOP to reset before complaining to user; - * the time for IOP to come to RESET state after it receives the - * EXEC_IOP_RESET really depends on the I2O hardware configured - * under the IOP. - */ - init_time = 5 * 60 * 100; /* ~5 min of clock ticks */ - -try_again: - if (i2o_get_iop_status(iop) == FAILURE) - goto cleanup; - - /* Check for I2O Version; we only support version 1.5 */ - if (get_i2o_exec_status_reply_I2oVersion(iop->status.bufp, - iop->status.acc_hdl) != I2O_VERSION_11) - goto cleanup; - - DEBUGF(I2O_DEBUG_DEBUG, - (CE_CONT, "i2o_msg_iop_init: Initial IOP state %x", - iop->status.bufp->IopState)); - - switch (iop->status.bufp->IopState) { - case I2O_IOP_STATE_RESET: - break; - - case I2O_IOP_STATE_INITIALIZING: - if (init_time <= 0) - cmn_err(CE_WARN, - "IOP is still in I2O_IOP_STATE_INITIALIZING state!!"); - else - init_time -= 100; - delay(100); - goto try_again; - - case I2O_IOP_STATE_OPERATIONAL: - /* reset the IOP and wait for a while for the IOP to reset */ - if (reset_done || i2o_send_exec_iop_reset(iop) != SUCCESS) - goto cleanup; - reset_done = 1; - delay(iop_reset_time_delay_in_ticks); - goto try_again; - - case I2O_IOP_STATE_HOLD: - case I2O_IOP_STATE_READY: - case I2O_IOP_STATE_FAILED: - case I2O_IOP_STATE_FAULTED: - /* reset the IOP and try again */ - if (!reset_done && i2o_send_exec_iop_reset(iop) == SUCCESS) { - delay(iop_reset_time_delay_in_ticks); - reset_done = 1; - goto try_again; - } - default: - cmn_err(CE_CONT, "?i2o_msg_iop_init: Invalid IOP state %x", - iop->status.bufp->IopState); - goto cleanup; - } - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_STATUS) - dump_iop_status_buf(iop); -#endif - - /* - * ************************************************************** - * Step 2: Initialize the Outbound message queue. - * ************************************************************** - */ - if (i2o_init_outbound_queue(iop) == FAILURE) - goto cleanup; - - /* - * ************************************************************** - * Step 3: Get the Hardware Resource Table (HRT). - * ************************************************************** - */ - if (i2o_get_hrt(iop) == FAILURE) - goto cleanup; - -#if !defined(I2O_BOOT_SUPPORT) - /* - * ************************************************************** - * Step 4: Allocate Memory/IO spaces required by the IOP to - * configure the hidden adapters. The IOP status buffer - * has the required information. - * - * XXX Does IOP handle multiple chunks for PCI memory/io space - * allocated by the host? Currently the IRTOS always reports - * the CurrentPrivateMemSize as zero. - * ************************************************************** - */ - priv_mem_size = ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->DesiredPrivateMemSize); - if (priv_mem_size > (uint32_t)0) { - /* need to allocate PCI memory space */ - if (i2o_get_mem(dip, priv_mem_size, &iop->hw_config.mem_base) == 0) - goto cleanup; - iop->hw_config.mem_size = priv_mem_size; - } - - priv_io_size = ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->DesiredPrivateIOSize); - if (priv_io_size > (uint32_t)0) { - /* need to allocate PCI i/o space */ - if (i2o_get_io(dip, priv_io_size, &iop->hw_config.io_base) == 0) - goto cleanup; - iop->hw_config.io_size = priv_io_size; - } -#endif - - /* - * ************************************************************** - * Step 5: Create the System Table entry for this IOP and send - * ExecSysTabSet to all the IOPs. It enables the IOP - * to OPERATIONAL state. - * ************************************************************** - */ - if (i2o_create_systab(iop) == FAILURE) - goto cleanup; - - ASSERT(iop->status.bufp->IopState == I2O_IOP_STATE_OPERATIONAL); - - /* - * ************************************************************** - * Step 6: Read LCT by sending ExecLctNotify message. - * ************************************************************** - */ - if (i2o_get_lct(iop) == FAILURE) - goto cleanup; - - /* - * ************************************************************** - * Step 7: Set event notification request for the events that - * we are interested. - * ************************************************************** - */ - if (i2o_iop_event_register(iop) == FAILURE) - goto cleanup; - - if (ioplist == NULL) { - ioplist = iop; - iop->next = NULL; - } else { - iop->next = ioplist; - ioplist = iop; - } - iop->iop_flags |= IOP_IS_ONLINE; - iop->ib_msg_frame_size = ddi_get16(iop->nexus_trans->acc_handle, - &iop->status.bufp->InboundMFrameSize) << 2; - - /* find the max TIDs allocated by the IOP */ - iop->osm_registry.max_tid = 0; - lct_entries = - ((ddi_get16(iop->lct.acc_hdl, &iop->lct.bufp->TableSize) << 2) - - sizeof (i2o_lct_t) + sizeof (i2o_lct_entry_t)) / - sizeof (i2o_lct_entry_t); - lct_entp = iop->lct.bufp->LCTEntry; - for (i = 0; i < lct_entries; i++) { - uint_t tid; - - tid = get_lct_entry_LocalTID(&lct_entp[i], iop->lct.acc_hdl); - if (tid > iop->osm_registry.max_tid) - iop->osm_registry.max_tid = tid; - } - - /* allocate the IOP handle table */ - iop->osm_registry.iop_handle_tab = (i2o_iop_impl_hdl_t *) - kmem_zalloc(sizeof (i2o_iop_impl_hdl_t) * - (iop->osm_registry.max_tid + 1), KM_SLEEP); - /* - * initialize the IOP handle (i2o_iop_handle_t) for the nexus to use and - * return the handle. - */ - hdl = &iop->osm_registry.iop_handle_tab[I2O_IOP_TID]; - hdl->dip = dip; - hdl->iop = iop; - hdl->tid = I2O_IOP_TID; - - mutex_exit(&i2o_mutex); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, "i2o_msg_iop_init: SUCCEEDED")); - - return ((i2o_iop_handle_t *)hdl); - - /* - * Error return; free up the allocated resources and return NULL. - */ -cleanup: - - if (iop->status.bufp != NULL) { - ddi_dma_mem_free(&iop->status.acc_hdl); - ddi_dma_free_handle(&iop->status.dma_handle); - } - - if (iop->lct.bufp != NULL) { - ddi_dma_mem_free(&iop->lct.acc_hdl); - ddi_dma_free_handle(&iop->lct.dma_handle); - } - - if (iop->hrt.bufp != NULL) { - ddi_dma_mem_free(&iop->hrt.acc_hdl); - ddi_dma_free_handle(&iop->hrt.dma_handle); - } - - if (iop->ob_msg_queue.base_addr != NULL) { - ddi_dma_mem_free(&iop->ob_msg_queue.acc_hdl); - ddi_dma_free_handle(&iop->ob_msg_queue.dma_handle); - } - - if (iop->hw_config.mem_base != NULL) { - i2o_return_mem(dip, iop->hw_config.mem_base, - iop->hw_config.mem_size); - } - - if (iop->hw_config.io_base != NULL) { - i2o_return_io(dip, iop->hw_config.io_base, - iop->hw_config.io_size); - } - - mutex_destroy(&iop->iop_ib_mutex); - mutex_destroy(&iop->iop_ob_mutex); - mutex_destroy(&iop->lct.lct_mutex); - - kmem_free((void *)iop, sizeof (iop_instance_t)); - - --niop; - - mutex_exit(&i2o_mutex); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, "i2o_msg_iop_init: FAILED")); - - return (NULL); -} - -/* - * i2o_msg_iop_unint() - * - * Called from the detach(9E) function in the i2o nexus driver. - * It would uninitialize IOP by sending ExecIopReset to bring the - * IOP to RESET state. And then it will free up any resources/data-structures - * allocated for this IOP instance. - * - * Assumption(s): - * 1. It is assumed that all the I2O devices are quiesced before calling - * this function. Which means all OSMs have already done the - * i2o_msg_osm_unregister() for the devices they claimed. - */ - -int -i2o_msg_iop_uninit(i2o_iop_handle_t *handlep) -{ - i2o_iop_handle_t h = *handlep; - iop_instance_t *iop = ((i2o_iop_impl_hdl_t *)(h))->iop; - ddi_dma_handle_t dma_handle = NULL; - ddi_acc_handle_t acc_hdl; - i2o_exec_iop_reset_status_t *buf = NULL; - i2o_exec_sys_quiesce_message_t *qmsgp; - i2o_single_reply_message_frame_t *rmp = NULL; - iop_instance_t *p; - - mutex_enter(&iop->iop_ib_mutex); - mutex_enter(&iop->iop_ob_mutex); - mutex_enter(&iop->osm_registry.osm_mutex); - mutex_enter(&iop->lct.lct_mutex); - mutex_enter(&i2o_mutex); - - /* - * First, disable the IOP hardware interrupts. - */ - (* iop->nexus_trans->i2o_trans_disable_intr) - (iop->nexus_trans->nexus_handle); - - /* - * ********************************************************* - * if there are multiple IOPs then we need to send - * ExecPathQuiesce message to other IOPs before - * resetting this IOP. - * ********************************************************* - */ - - if (niop > 1) { /* we have multiple IOPs */ - tcontext_t tcxt; /* transaction context structure */ - - cv_init(&tcxt.cv, NULL, CV_DEFAULT, NULL); - mutex_init(&tcxt.cv_mutex, NULL, MUTEX_DRIVER, NULL); - - for (p = ioplist; p != NULL; p = p->next) { - i2o_exec_path_quiesce_message_t *mp; - - if (p == iop) - continue; - - /* - * Send ExecPathQuiesce message to this IOP. - */ - - mp = (i2o_exec_path_quiesce_message_t *)iop_msg_alloc(p); - - if (mp == NULL) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_msg_iop_uninit: trans_msg_alloc failed")); - cv_destroy(&tcxt.cv); - mutex_destroy(&tcxt.cv_mutex); - goto cleanup; - } - - /* initialize the transcation context structure */ - tcxt.iop = p; - tcxt.done_flag = 0; - - /* construct the ExecPathQuiesce message */ - - init_std_msghdr(p, &mp->StdMessageFrame, 0x0, 0, - sizeof (i2o_exec_path_quiesce_message_t), - I2O_EXEC_PATH_QUIESCE); - ddi_put32(p->nexus_trans->acc_handle, - &mp->TransactionContext, (uint32_t)(uintptr_t)&tcxt); - ddi_put32(p->nexus_trans->acc_handle, - (uint32_t *)&mp->StdMessageFrame.InitiatorContext. - initiator_context_32bits, - (uint32_t)i2o_msg_common_reply); - put_i2o_exec_path_quiesce_IOP_ID(mp, iop->iop_id, - p->nexus_trans->acc_handle); - ddi_put16(p->nexus_trans->acc_handle, - &mp->HostUnitID, iop->status.bufp->HostUnitID); - - /* send the message to the IOP and wait for the reply */ - - (void) iop_msg_send(p, (void *)mp); - - mutex_enter(&tcxt.cv_mutex); - while (!tcxt.done_flag) /* wait for the reply */ - cv_wait(&tcxt.cv, &tcxt.cv_mutex); - mutex_exit(&tcxt.cv_mutex); - } - - cv_destroy(&tcxt.cv); - mutex_destroy(&tcxt.cv_mutex); - } - - - /* - * ********************************************************* - * Send an ExecSysQuiesce message to the IOP. - * ********************************************************* - */ - - /* allocate a message frame from Inbound queue */ - qmsgp = (i2o_exec_sys_quiesce_message_t *)iop_msg_alloc(iop); - if (qmsgp == NULL) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_msg_iop_uninit: trans_msg_alloc failed")); - goto cleanup; - } - - /* construct the ExecSysQuiesce message */ - init_std_msghdr(iop, &qmsgp->StdMessageFrame, 0x0, 0, - sizeof (i2o_exec_sys_quiesce_message_t), - I2O_EXEC_SYS_QUIESCE); - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_message((uint32_t *)qmsgp, "ExecSysQuiesce"); -#endif - - /* send the message to the IOP */ - (void) iop_msg_send(iop, (void *)qmsgp); - - /* - * Since interrupts are disabled, we poll for the reply message - * for ExecSysQuiesce request. Could we expect any other reply - * messages for previous activity on this IOP (like some - * event notification)? For now, we can safely ignore any other - * reply messages. - */ - for (;;) { - - if ((rmp = iop_poll_reply_msg(iop)) == NULL) - goto cleanup; - - /* ignore reply messages other than for ExecSysQuiesce */ - if (get_msg_Function((i2o_message_frame_t *)rmp, - iop->ob_msg_queue.acc_hdl) != I2O_EXEC_SYS_QUIESCE) { - iop_msg_free(iop, rmp); - continue; - } - - if (rmp->ReqStatus == I2O_REPLY_STATUS_SUCCESS) - break; /* successful */ - - /* message failed */ - iop_msg_free(iop, rmp); - goto cleanup; - } - - /* free up the reply message buffer */ - iop_msg_free(iop, rmp); - - /* - * ********************************************************* - * Now, send an ExecIopReset message to the IOP. - * ********************************************************* - */ - - if (i2o_send_exec_iop_reset(iop) == FAILURE) - goto cleanup; - - iop->iop_flags |= IOP_IS_IN_UNINIT; - - /* - * ********************************************************* - * Free up the system resources. - * ********************************************************* - */ - if (iop->status.bufp != NULL) { - ddi_dma_mem_free(&iop->status.acc_hdl); - ddi_dma_free_handle(&iop->status.dma_handle); - } - - if (iop->lct.bufp != NULL) { - ddi_dma_mem_free(&iop->lct.acc_hdl); - ddi_dma_free_handle(&iop->lct.dma_handle); - } - - if (iop->hrt.bufp != NULL) { - ddi_dma_mem_free(&iop->hrt.acc_hdl); - ddi_dma_free_handle(&iop->hrt.dma_handle); - } - - if (iop->ob_msg_queue.base_addr != NULL) { - ddi_dma_mem_free(&iop->ob_msg_queue.acc_hdl); - ddi_dma_free_handle(&iop->ob_msg_queue.dma_handle); - } - - if (iop->hw_config.mem_base != NULL) { - i2o_return_mem(iop->dip, iop->hw_config.mem_base, - iop->hw_config.mem_size); - } - - if (iop->hw_config.io_base != NULL) { - i2o_return_io(iop->dip, iop->hw_config.io_base, - iop->hw_config.io_size); - } - - /* - * If i2o_msg_send_proc() is running then wait for it to exit. - */ - if (iop->iop_flags & IOP_SEND_QUEUE_PROC_RUNNING) { - - mutex_exit(&iop->iop_ib_mutex); - - /* wake up the i2o_msg_send_proc() thread */ - cv_broadcast(&iop->send_queue_cv); - - /* wait until the i2o_msg_send_proc() stops running */ - while (iop->iop_flags & IOP_SEND_QUEUE_PROC_RUNNING) - delay(1); - - cv_destroy(&iop->send_queue_cv); - } - - mutex_destroy(&iop->iop_ib_mutex); - mutex_destroy(&iop->iop_ob_mutex); - mutex_destroy(&iop->osm_registry.osm_mutex); - mutex_destroy(&iop->lct.lct_mutex); - - if (iop == ioplist) { - ioplist = ioplist->next; - } else { - iop_instance_t *p, *prev; - - for (prev = ioplist, p = ioplist->next; p; p = p->next) { - if (p == iop) { - prev->next = iop->next; - break; - } - prev = p; - } - - ASSERT((p != NULL) && (p == iop)); - } - - --niop; /* number of active IOPs */ - - mutex_exit(&i2o_mutex); - - /* free up the IOP handle table */ - kmem_free((void *)iop->osm_registry.iop_handle_tab, - sizeof (i2o_iop_impl_hdl_t) * (iop->osm_registry.max_tid + 1)); - - *handlep = NULL; - - kmem_free((void *)iop, sizeof (iop_instance_t)); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, "i2o_msg_iop_uninit: SUCCEEDED")); - - return (DDI_SUCCESS); - - /* - * Error return; free up the allocated resources and return NULL. - */ -cleanup: - if (buf != NULL) - ddi_dma_mem_free(&acc_hdl); - - if (dma_handle != NULL) - ddi_dma_free_handle(&dma_handle); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, "i2o_msg_iop_uninit: FAILED")); - - mutex_exit(&i2o_mutex); - mutex_exit(&iop->lct.lct_mutex); - mutex_exit(&iop->osm_registry.osm_mutex); - mutex_exit(&iop->iop_ob_mutex); - mutex_exit(&iop->iop_ib_mutex); - - return (DDI_FAILURE); -} - -/* - * Send ExecStatusGet message to get IOP status. It allocates the - * buffer resources if they are not already allocated. - * - * Returns SUCCESS if it succeeds in getting the IOP status. - */ -static int -i2o_get_iop_status(iop_instance_t *iop) -{ - size_t real_length; - ddi_dma_cookie_t dma_cookie; - uint_t ncookies; - i2o_exec_status_get_message_t *msgp; - i2o_exec_status_get_reply_t *s = 0; - - if (iop->status.dma_handle == NULL) { - - /* allocate a DMA handle */ - if (ddi_dma_alloc_handle(iop->dip, &dma_attr_contig, DDI_DMA_SLEEP, - NULL, &iop->status.dma_handle) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_iop_status: ddi_dma_alloc_handle failed")); - goto cleanup; - } - } - - if (iop->status.bufp == NULL) { - - /* allocate the buffer for the IOP status block */ - if (ddi_dma_mem_alloc(iop->status.dma_handle, - sizeof (i2o_exec_status_get_reply_t), &i2o_dev_acc_attr, - DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, - (caddr_t *)&iop->status.bufp, &real_length, - &iop->status.acc_hdl) != DDI_SUCCESS) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_iop_status: ddi_dma_mem_alloc failed")); - goto cleanup; - } - - bzero((caddr_t)iop->status.bufp, real_length); - } - - if (ddi_dma_addr_bind_handle(iop->status.dma_handle, NULL, - (caddr_t)iop->status.bufp, sizeof (i2o_exec_status_get_reply_t), - DDI_DMA_READ | DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &dma_cookie, &ncookies) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_iop_status: cannot bind memory")); - goto cleanup; - } - - ASSERT(ncookies == 1); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_iop_status: dma_bind (vaddr %p paddr %x length %x)", - (void *)iop->status.bufp, dma_cookie.dmac_address, - (int)dma_cookie.dmac_size)); - - /* allocate a message frame from Inbound queue */ - msgp = (i2o_exec_status_get_message_t *)iop_msg_alloc(iop); - if (msgp == NULL) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_iop_status: trans_msg_alloc failed")); - (void) ddi_dma_unbind_handle(iop->status.dma_handle); - goto cleanup; - } - - /* construct the ExecStatusGet message */ - init_std_msghdr(iop, (i2o_message_frame_t *)msgp, 0x0, 0, - sizeof (i2o_exec_status_get_message_t), - I2O_EXEC_STATUS_GET); - ddi_put32(iop->nexus_trans->acc_handle, &msgp->ReplyBufferAddressLow, - dma_cookie.dmac_address); - ddi_put32(iop->nexus_trans->acc_handle, - &msgp->ReplyBufferAddressHigh, 0); - ddi_put32(iop->nexus_trans->acc_handle, &msgp->ReplyBufferLength, - sizeof (i2o_exec_status_get_reply_t)); - iop->status.bufp->SyncByte = 0; - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_message((uint32_t *)msgp, "ExecStatusGet"); -#endif - - /* send the message to the IOP */ - (void) iop_msg_send(iop, (void *)msgp); - - /* - * Poll on the status block field 'SyncByte' because there is - * no reply to ExecStatusGet message. The IOP writes '0xFF' - * to 'SyncByte' field when it finished writing to the status - * block structure. - */ - - while (iop->status.bufp->SyncByte != 0xFF) { - delay(1); - /* sync DMA memory */ - (void) ddi_dma_sync(iop->status.dma_handle, - (off_t)&s->SyncByte, 1, DDI_DMA_SYNC_FORCPU); - } - - (void) ddi_dma_unbind_handle(iop->status.dma_handle); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, "i2o_get_iop_status: SUCCEEDED")); - - return (SUCCESS); - - /* - * Error return; free up the allocated resources and return NULL. - */ -cleanup: - - if (iop->status.bufp != NULL) { - ddi_dma_mem_free(&iop->status.acc_hdl); - iop->status.bufp = NULL; - } - - if (iop->status.dma_handle != NULL) { - ddi_dma_free_handle(&iop->status.dma_handle); - iop->status.dma_handle = NULL; - } - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, "i2o_get_iop_status: FAILED")); - - return (FAILURE); -} - -/* - * Allocate message frames for the Outbound queue and send ExecOutboundInit - * message to the IOP. - * - * Description: - * Since we don't know how to determine how many frames to be - * allocated, we either depend on the user specified property - * (i.e ob-msg-queue-length) or use the current IOP's default. - * Allocate the message queue as one physically contiguous chunk. - * Send ExecOutboundInit message with the list of MFAs. - */ -static int -i2o_init_outbound_queue(iop_instance_t *iop) -{ - size_t real_length; - ddi_dma_cookie_t dma_cookie; - uint_t ncookies; - i2o_exec_outbound_init_message_t *msgp; - int nframes, max_nframes; - int frame_size; - i2o_sge_simple_element_t *sgl; - i2o_exec_outbound_init_status_t *stat; - uint_t mfa; - int count; - - if (iop->ob_msg_queue.dma_handle == NULL) { - - /* allocate a DMA handle */ - if (ddi_dma_alloc_handle(iop->dip, &dma_attr_contig, DDI_DMA_SLEEP, - NULL, &iop->ob_msg_queue.dma_handle) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_init_outbound_queue: ddi_dma_alloc_handle failed")); - goto cleanup; - } - } - - if (iop->ob_msg_queue.base_addr == NULL) { - - nframes = ddi_prop_get_int(DDI_DEV_T_ANY, iop->dip, - DDI_PROP_DONTPASS, "ob-msg-queue-length", - ob_msg_queue_length_default); - - max_nframes = ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->MaxOutboundMFrames); - - if (nframes == 0 || nframes > max_nframes) - nframes = max_nframes; - - frame_size = ddi_prop_get_int(DDI_DEV_T_ANY, iop->dip, - DDI_PROP_DONTPASS, "ob-msg-framesize", - ob_msg_framesize_default); - - /* allocate the buffer for the message frames */ - if (ddi_dma_mem_alloc(iop->ob_msg_queue.dma_handle, - (size_t)(nframes * frame_size), &i2o_dev_acc_attr, - DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, - (caddr_t *)&iop->ob_msg_queue.base_addr, &real_length, - &iop->ob_msg_queue.acc_hdl) != DDI_SUCCESS) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_init_outbound_queue: ddi_dma_mem_alloc failed")); - goto cleanup; - } - bzero((caddr_t)iop->ob_msg_queue.base_addr, real_length); - iop->ob_msg_queue.nframes = nframes; - iop->ob_msg_queue.framesize = frame_size; - } - - if (ddi_dma_addr_bind_handle(iop->ob_msg_queue.dma_handle, NULL, - iop->ob_msg_queue.base_addr, - (iop->ob_msg_queue.nframes * iop->ob_msg_queue.framesize), - DDI_DMA_READ | DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &dma_cookie, &ncookies) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_init_outbound_queue: cannot bind memory")); - goto cleanup; - } - - ASSERT(ncookies == 1); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_init_outbound_queue: dma_bind (vaddr %p paddr %x length %x)", - (void *)iop->ob_msg_queue.base_addr, dma_cookie.dmac_address, - (int)dma_cookie.dmac_size)); - - iop->ob_msg_queue.base_paddr = (uint_t)dma_cookie.dmac_address; - - /* allocate a message frame from Inbound queue */ - msgp = (i2o_exec_outbound_init_message_t *)iop_msg_alloc(iop); - if (msgp == NULL) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_init_outbound_queue: trans_msg_alloc failed")); - - (void) ddi_dma_unbind_handle(iop->ob_msg_queue.dma_handle); - goto cleanup; - } - - /* - * Construct the ExecOutboundInit message. Use the base address - * of the outbound message queue buffer for the status word structure - * instead of allocating a new word. - */ - init_std_msghdr(iop, &msgp->StdMessageFrame, 0x60, 0, - sizeof (i2o_exec_outbound_init_message_t), - I2O_EXEC_OUTBOUND_INIT); - ddi_put32(iop->nexus_trans->acc_handle, &msgp->HostPageFrameSize, - MMU_PAGESIZE); - msgp->InitCode = I2O_MESSAGE_IF_INIT_CODE_OS; - ddi_put16(iop->nexus_trans->acc_handle, &msgp->OutboundMFrameSize, - ((uint16_t)frame_size) >> 2); - - sgl = (i2o_sge_simple_element_t *)&msgp->SGL; - init_sgl_simple_ele(iop, sgl, - I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER, - 4, (uint_t)iop->ob_msg_queue.base_paddr); - - stat = (i2o_exec_outbound_init_status_t *)iop->ob_msg_queue.base_addr; - stat->InitStatus = 0; - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_message((uint32_t *)msgp, "ExecOutboundInit"); -#endif - - /* send the message to the IOP */ - (void) iop_msg_send(iop, (void *)msgp); - - /* - * Poll on the status word for completion. - */ - while ((stat->InitStatus == 0) || - (stat->InitStatus == I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS)) { - - delay(2); - /* sync DMA memory */ - (void) ddi_dma_sync(iop->ob_msg_queue.dma_handle, - 0, 1, DDI_DMA_SYNC_FORCPU); - } - - (void) ddi_dma_unbind_handle(iop->ob_msg_queue.dma_handle); - - if (stat->InitStatus != I2O_EXEC_OUTBOUND_INIT_COMPLETE) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_init_outbound_queue: FAILED (InitStatus %x)", - stat->InitStatus)); - goto cleanup; - } - - /* - * Now, write the MFAs to the Outbound FIFO. - */ - mfa = iop->ob_msg_queue.base_paddr; - for (count = 0; count < iop->ob_msg_queue.nframes; count ++) { - (* iop->nexus_trans->i2o_trans_msg_freebuf) - (iop->nexus_trans->nexus_handle, mfa); - mfa += iop->ob_msg_queue.framesize; - } - - DEBUGF(I2O_DEBUG_DEBUG, - (CE_CONT, "i2o_init_outbound_queue: SUCCEEDED")); - - return (SUCCESS); - - - /* - * Error return; free up the allocated resources and return NULL. - */ -cleanup: - - if (iop->ob_msg_queue.base_addr != NULL) { - ddi_dma_mem_free(&iop->ob_msg_queue.acc_hdl); - iop->ob_msg_queue.base_addr = NULL; - } - - if (iop->ob_msg_queue.dma_handle != NULL) { - ddi_dma_free_handle(&iop->ob_msg_queue.dma_handle); - iop->ob_msg_queue.dma_handle = NULL; - } - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, "i2o_init_outbound_queue: FAILED")); - - return (FAILURE); -} - -/* - * Get HRT by sending ExecHrtGet message to the IOP. - * It is assumed that Outbound queue is already initialized - * so that the IOP can send a reply to the ExecHrtGet message. - * Also it is assumed that the IOP interrupts are disabled. - */ -static int -i2o_get_hrt(iop_instance_t *iop) -{ - size_t real_length; - ddi_dma_cookie_t dma_cookie; - uint_t ncookies; - i2o_exec_hrt_get_message_t *msgp; - i2o_hrt_t *buf = NULL; - ddi_acc_handle_t acc_hdl; - i2o_single_reply_message_frame_t *rmp = NULL; - uint_t hrt_size; - - /* allocate a DMA handle if necessary */ - if (iop->hrt.dma_handle == NULL) { - if (ddi_dma_alloc_handle(iop->dip, &dma_attr_contig, DDI_DMA_SLEEP, - NULL, &iop->hrt.dma_handle) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_hrt: ddi_dma_alloc_handle failed")); - goto cleanup; - } - } - - /* - * Allocate a temporary buffer to get the HRT size information - * (i.e only header part of the HRT). - */ - if (ddi_dma_mem_alloc(iop->hrt.dma_handle, - sizeof (i2o_hrt_t), &i2o_dev_acc_attr, - DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, (caddr_t *)&buf, - &real_length, &acc_hdl) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_hrt: ddi_dma_mem_alloc failed")); - goto cleanup; - } - - bzero((caddr_t)buf, real_length); - - if (ddi_dma_addr_bind_handle(iop->hrt.dma_handle, NULL, (caddr_t)buf, - real_length, DDI_DMA_READ | DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &dma_cookie, &ncookies) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_hrt: cannot bind memory")); - goto cleanup; - } - - ASSERT(ncookies == 1); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_hrt: dma_bind (vaddr %p paddr %x length %x)", - (void *)buf, dma_cookie.dmac_address, - (int)dma_cookie.dmac_size)); - - /* allocate a message frame from Inbound queue */ - msgp = (i2o_exec_hrt_get_message_t *)iop_msg_alloc(iop); - if (msgp == NULL) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_hrt: trans_msg_alloc failed")); - (void) ddi_dma_unbind_handle(iop->hrt.dma_handle); - goto cleanup; - } - - /* - * Construct the ExecHrtGet message. - */ - init_std_msghdr(iop, &msgp->StdMessageFrame, 0x40, 0, - sizeof (i2o_exec_hrt_get_message_t), I2O_EXEC_HRT_GET); - init_sgl_simple_ele(iop, msgp->SGL.u1.Simple, - I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER, - sizeof (i2o_hrt_t), (uint_t)dma_cookie.dmac_address); - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_message((uint32_t *)msgp, "ExecHrtGet"); -#endif - - /* send the message to the IOP */ - (void) iop_msg_send(iop, (void *)msgp); - - /* since interrupts are disabled, we poll for the reply message */ - rmp = iop_poll_reply_msg(iop); - if ((rmp == NULL) || (rmp->ReqStatus != I2O_REPLY_STATUS_SUCCESS)) { - if (rmp) - iop_msg_free(iop, rmp); - (void) ddi_dma_unbind_handle(iop->hrt.dma_handle); - goto cleanup; - } - - ASSERT(get_msg_Function((i2o_message_frame_t *)rmp, - iop->ob_msg_queue.acc_hdl) == I2O_EXEC_HRT_GET); /* paranoia? */ - - /* free up the reply message buffer */ - iop_msg_free(iop, rmp); - - ASSERT(buf->HRTVersion == 0); /* HRT version for 1.5 is 0x00 */ - - hrt_size = (sizeof (i2o_hrt_t) - sizeof (i2o_hrt_entry_t)) + - (sizeof (i2o_hrt_entry_t) * - ddi_get16(acc_hdl, &buf->NumberEntries)); - - /* - * NOTE: Some old versions of RTOS is not setting the EntryLength - * correctly. Also, I am not sure if all implementations of RTOS - * set this field. So, the following ASSERTION is disabled. - * - * ASSERT((buf->EntryLength * 4) == sizeof (i2o_hrt_entry_t)); - */ - - /* free up the temporary buffer */ - (void) ddi_dma_unbind_handle(iop->hrt.dma_handle); - ddi_dma_mem_free(&acc_hdl); - buf = NULL; - - /* - * Now, allocate the correct size buffer for HRT and send another - * ExecHrtGet message. - */ - if (iop->hrt.bufp == NULL || (iop->hrt.size < hrt_size)) { - - /* free up any old buffer */ - if (iop->hrt.bufp != NULL) { - ddi_dma_mem_free(&iop->hrt.acc_hdl); - iop->hrt.bufp = NULL; - } - - iop->hrt.size = hrt_size; - - /* allocate a new buffer for HRT */ - if (ddi_dma_mem_alloc(iop->hrt.dma_handle, - iop->hrt.size, &i2o_dev_acc_attr, DDI_DMA_CONSISTENT, - DDI_DMA_SLEEP, NULL, (caddr_t *)&iop->hrt.bufp, - &real_length, &iop->hrt.acc_hdl) != DDI_SUCCESS) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_hrt: ddi_dma_mem_alloc failed")); - goto cleanup; - } - bzero((caddr_t)iop->hrt.bufp, real_length); - } - - if (ddi_dma_addr_bind_handle(iop->hrt.dma_handle, NULL, - (caddr_t)iop->hrt.bufp, iop->hrt.size, - DDI_DMA_READ | DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &dma_cookie, &ncookies) != DDI_SUCCESS) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_hrt: cannot bind memory")); - goto cleanup; - } - - ASSERT(ncookies == 1); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_hrt: dma_bind (vaddr %p paddr %x length %x)", - (void *)iop->hrt.bufp, dma_cookie.dmac_address, - (int)dma_cookie.dmac_size)); - - /* allocate a message frame from Inbound queue */ - msgp = (i2o_exec_hrt_get_message_t *)iop_msg_alloc(iop); - if (msgp == NULL) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_hrt: trans_msg_alloc failed")); - (void) ddi_dma_unbind_handle(iop->hrt.dma_handle); - goto cleanup; - } - - /* - * Construct the ExecHrtGet message (again!). - */ - init_std_msghdr(iop, &msgp->StdMessageFrame, 0x40, 0, - sizeof (i2o_exec_hrt_get_message_t), I2O_EXEC_HRT_GET); - init_sgl_simple_ele(iop, msgp->SGL.u1.Simple, - I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER, - hrt_size, (uint_t)dma_cookie.dmac_address); - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_message((uint32_t *)msgp, "ExecHrtGet"); -#endif - - /* send the message to the IOP */ - (void) iop_msg_send(iop, (void *)msgp); - - /* since interrupts are disabled, we poll for the reply message */ - rmp = iop_poll_reply_msg(iop); - if ((rmp == NULL) || (rmp->ReqStatus != I2O_REPLY_STATUS_SUCCESS)) { - if (rmp) - iop_msg_free(iop, rmp); -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_reply_message(iop, rmp); -#endif - (void) ddi_dma_unbind_handle(iop->hrt.dma_handle); - goto cleanup; - } - - ASSERT(get_msg_Function((i2o_message_frame_t *)rmp, - iop->ob_msg_queue.acc_hdl) == I2O_EXEC_HRT_GET); /* paranoia? */ - - /* free up the reply message buffer */ - iop_msg_free(iop, rmp); - - (void) ddi_dma_unbind_handle(iop->hrt.dma_handle); - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_HRT) - dump_hrt(iop); -#endif - - return (SUCCESS); - - /* - * Error return; free up the allocated resources and return NULL. - */ -cleanup: - - if (buf != NULL) - ddi_dma_mem_free(&acc_hdl); - - if (iop->hrt.bufp != NULL) { - ddi_dma_mem_free(&iop->hrt.acc_hdl); - iop->hrt.bufp = NULL; - } - - if (iop->hrt.dma_handle != NULL) { - ddi_dma_free_handle(&iop->hrt.dma_handle); - iop->hrt.dma_handle = NULL; - } - - return (FAILURE); -} - - -/* - * Create the system table entry for the IOP and update all IOPs with - * the latest System Table. It sends ExecSysTabSet message to all - * IOPs. If necessary it sends the ExecSysEnable to the new IOP that - * is being initialized. - * - * Note: It is assumed that this routine is called from the IOP init - * routine. - */ -static int -i2o_create_systab(iop_instance_t *iop) -{ - ddi_dma_handle_t dma_handle = NULL; - ddi_acc_handle_t acc_hdl; - size_t real_length; - ddi_dma_cookie_t dma_cookie; - uint_t ncookies; - i2o_iop_entry_t *entp; - i2o_set_systab_header_t *systab = NULL; - i2o_iop_entry_t *systab_entryp; - int i; - iop_instance_t *p; - i2o_exec_sys_tab_set_message_t *msgp; - i2o_single_reply_message_frame_t *rmp = NULL; - uint_t systab_size; - tcontext_t tcxt; /* transaction context structure */ - - - /* - * ********************************************************* - * Create SysTab entry for this IOP. - * ********************************************************* - */ - if (ddi_dma_alloc_handle(iop->dip, &dma_attr_contig, DDI_DMA_SLEEP, - NULL, &iop->systab.dma_handle) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_create_systab: ddi_dma_alloc_handle failed")); - goto cleanup; - } - - /* allocate the buffer for systab entry */ - if (ddi_dma_mem_alloc(iop->systab.dma_handle, sizeof (i2o_iop_entry_t), - &i2o_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, - (caddr_t *)&iop->systab.bufp, &real_length, - &iop->systab.acc_hdl) != DDI_SUCCESS) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_create_systab: ddi_dma_mem_alloc failed")); - goto cleanup; - } - - bzero((caddr_t)iop->systab.bufp, real_length); - - /* - * initialize the systab entry with the information from the iop - * status buffer. - */ - entp = iop->systab.bufp; - entp->OrganizationID = iop->status.bufp->OrganizationID; - entp->IopCapabilities = iop->status.bufp->IopCapabilities; - entp->InboundMessageFrameSize = - iop->status.bufp->InboundMFrameSize; - entp->MessengerType = iop->status.bufp->MessengerType; - entp->IopState = I2O_IOP_STATE_OPERATIONAL; /* expected state */ - put_i2o_iop_entry_I2oVersion(entp, - get_i2o_exec_status_reply_I2oVersion(iop->status.bufp, - iop->status.acc_hdl), iop->systab.acc_hdl); - put_i2o_iop_entry_SegmentNumber(entp, - get_i2o_exec_status_reply_SegmentNumber(iop->status.bufp, - iop->status.acc_hdl), iop->systab.acc_hdl); - put_i2o_iop_entry_IOP_ID(entp, iop->iop_id, iop->systab.acc_hdl); - ddi_put32(iop->systab.acc_hdl, - &entp->MessengerInfo.InboundMessagePortAddressLow, - iop->nexus_trans->iop_inbound_fifo_paddr); - ddi_put32(iop->systab.acc_hdl, - &entp->MessengerInfo.InboundMessagePortAddressHigh, 0); - - /* - * ********************************************************* - * Create a System Table for sending ExecSysTabSet message - * to all IOP(s). - * ********************************************************* - */ - /* allocate the buffer for systab header and for the systab entries */ - systab_size = sizeof (i2o_set_systab_header_t) + - (niop * sizeof (i2o_iop_entry_t)); - - if (ddi_dma_alloc_handle(iop->dip, &dma_attr_contig, DDI_DMA_SLEEP, - NULL, &dma_handle) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_create_systab: ddi_dma_alloc_handle failed")); - goto cleanup; - } - - if (ddi_dma_mem_alloc(dma_handle, systab_size, - &i2o_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, - (caddr_t *)&systab, &real_length, - &acc_hdl) != DDI_SUCCESS) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_create_systab: ddi_dma_mem_alloc failed")); - goto cleanup; - } - - bzero((caddr_t)systab, real_length); - - /* fill in the systab header and systab entries */ - systab->NumberEntries = niop; - systab->SysTabVersion = I2O_VERSION_11; - ddi_put32(iop->systab.acc_hdl, &systab->CurrentChangeIndicator, - (uint32_t)(iop->iop_id - BASE_IOP_ID)); - - systab_entryp = (i2o_iop_entry_t *)&systab[1]; - iop->next = ioplist; - - for (p = iop, i = 0; i < niop; i++) { - systab_entryp[i] = p->systab.bufp[0]; - p = p->next; - } - - if (ddi_dma_addr_bind_handle(dma_handle, NULL, (caddr_t)systab, - real_length, DDI_DMA_WRITE | DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &dma_cookie, &ncookies) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_create_systab: cannot bind memory")); - goto cleanup; - } - - ASSERT(ncookies == 1); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_create_systab: dma_bind (vaddr %p paddr %x length %x)", - (void *)systab, dma_cookie.dmac_address, - (int)dma_cookie.dmac_size)); - - /* Now, send ExecSysTabSet message to each of the IOPs */ - for (p = iop, i = 0; i < niop; i++) { - - /* allocate a message frame from Inbound queue */ - msgp = (i2o_exec_sys_tab_set_message_t *)iop_msg_alloc(p); - if (msgp == NULL) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_create_systab: trans_msg_alloc failed")); - (void) ddi_dma_unbind_handle(dma_handle); - goto cleanup; - } - /* - * Construct the ExecSysTabSet message. - * - * Note: The implied assumption is that the message frame has - * enough room for 3 SGL elements. - */ - - init_std_msghdr(p, &msgp->StdMessageFrame, 0x40, 0, - sizeof (i2o_exec_sys_tab_set_message_t) + - 2 * sizeof (i2o_sg_element_t), I2O_EXEC_SYS_TAB_SET); - msgp->HostUnitID = 0; - put_i2o_exec_sys_tab_set_SegmentNumber(msgp, - get_i2o_exec_status_reply_SegmentNumber(p->status.bufp, - p->status.acc_hdl), p->systab.acc_hdl); - put_i2o_exec_sys_tab_set_IOP_ID(msgp, p->iop_id, - p->systab.acc_hdl); - - if (p != iop) { - /* - * For other IOPs we don't poll the reply, so - * setup the InitiatorContext/TransactionContext. - */ - cv_init(&tcxt.cv, NULL, CV_DEFAULT, NULL); - mutex_init(&tcxt.cv_mutex, NULL, MUTEX_DRIVER, NULL); - /* initialize the transcation context structure */ - tcxt.iop = p; - tcxt.done_flag = 0; - ddi_put32(p->nexus_trans->acc_handle, - &msgp->TransactionContext, - (uint32_t)(uintptr_t)&tcxt); - ddi_put32(p->nexus_trans->acc_handle, - (uint32_t *)&msgp->StdMessageFrame.InitiatorContext. - initiator_context_32bits, - (uint32_t)i2o_msg_common_reply); - } - - /* First buffer is for systab itself */ - init_sgl_simple_ele(p, &msgp->SGL.u1.Simple[0], - I2O_SGL_FLAGS_END_OF_BUFFER, systab_size, - (uint_t)dma_cookie.dmac_address); - - /* - * Second buffer is for Private Memory Space allocation. - * - * Note: The spec is not clear if this buffer can be NULL - * for the IOP which was already initialized to OP state - * and there is no change to its configuration. Here, we - * will set it to NULL assuming that it is ignored. - */ - if (p == iop) { - init_sgl_simple_ele(p, &msgp->SGL.u1.Simple[1], - I2O_SGL_FLAGS_END_OF_BUFFER, - p->hw_config.mem_size, (uint_t)p->hw_config.mem_base); - } else { - init_sgl_simple_ele(p, &msgp->SGL.u1.Simple[1], - I2O_SGL_FLAGS_END_OF_BUFFER, 0, 0); - } - - /* - * Third buffer is for Private IO Space allocation. - * - * Note: The spec is not clear if this buffer can be NULL - * for the IOP which was already initialized to OP state - * and there is no change to its configuration. Here, we - * will set it to NULL assuming that it is ignored. - */ - if (p == iop) { - init_sgl_simple_ele(p, &msgp->SGL.u1.Simple[2], - I2O_SGL_FLAGS_LAST_ELEMENT | - I2O_SGL_FLAGS_END_OF_BUFFER, - p->hw_config.io_size, (uint_t)p->hw_config.io_base); - } else { - init_sgl_simple_ele(p, &msgp->SGL.u1.Simple[2], - I2O_SGL_FLAGS_LAST_ELEMENT | - I2O_SGL_FLAGS_END_OF_BUFFER, 0, 0); - } - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_message((uint32_t *)msgp, "ExecSysTabSet"); -#endif - - /* send the message to the IOP */ - (void) iop_msg_send(p, (void *)msgp); - - /* wait for the reply message */ - if (p == iop) { - /* - * For this IOP, interrupts are disabled. So, we poll - * for the reply message. - */ - rmp = iop_poll_reply_msg(p); - - if ((rmp == NULL) || - (rmp->ReqStatus != I2O_REPLY_STATUS_SUCCESS)) { - - if (rmp) - iop_msg_free(p, rmp); -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_reply_message(p, rmp); -#endif - (void) ddi_dma_unbind_handle(dma_handle); - goto cleanup; - } - - /* paranoia? */ - ASSERT(get_msg_Function((i2o_message_frame_t *)rmp, - iop->ob_msg_queue.acc_hdl) == I2O_EXEC_SYS_TAB_SET); - - /* free up the reply message buffer */ - iop_msg_free(p, rmp); - - } else { - /* For other IOPs, wait for the reply message */ - mutex_enter(&tcxt.cv_mutex); - while (!tcxt.done_flag) /* wait for the reply */ - cv_wait(&tcxt.cv, &tcxt.cv_mutex); - mutex_exit(&tcxt.cv_mutex); - - cv_destroy(&tcxt.cv); - mutex_destroy(&tcxt.cv_mutex); - - /* check the status for SUCCESS */ - if (tcxt.status != I2O_REPLY_STATUS_SUCCESS) { - (void) ddi_dma_unbind_handle(dma_handle); - goto cleanup; - } - } - - /* - * For the new IOP, send the ExecSysEnable message. - */ - if (p == iop) { - if (i2o_send_exec_enable(iop) != SUCCESS) { - (void) ddi_dma_unbind_handle(dma_handle); - goto cleanup; - } - } - } - - (void) ddi_dma_unbind_handle(dma_handle); - - if (iop->status.bufp->IopState != I2O_IOP_STATE_OPERATIONAL) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_create_systab: invalid IOP state")); - goto cleanup; - } - - ddi_dma_mem_free(&acc_hdl); /* free the systab buffer */ - - ddi_dma_free_handle(&dma_handle); - - return (SUCCESS); - - /* - * Error return; free up the allocated resources and return NULL. - */ -cleanup: - - if (iop->systab.bufp != NULL) { - ddi_dma_mem_free(&iop->systab.acc_hdl); - iop->systab.bufp = NULL; - } - - if (iop->systab.dma_handle != NULL) { - ddi_dma_free_handle(&iop->systab.dma_handle); - iop->systab.dma_handle = NULL; - } - - if (systab != NULL) - ddi_dma_mem_free(&acc_hdl); - - if (dma_handle != NULL) - ddi_dma_free_handle(&dma_handle); - - return (FAILURE); -} - -/* - * Send the ExecSysEnable message to the IOP if it is in the - * READY state. It assumes that the IOP interrupts are disabled. - */ -static int -i2o_send_exec_enable(iop_instance_t *iop) -{ - i2o_exec_sys_enable_message_t *mp; - i2o_single_reply_message_frame_t *rmp = NULL; - - /* - * Get the current state of IOP. - */ - if (i2o_get_iop_status(iop) == FAILURE) - goto cleanup; - - if (iop->status.bufp->IopState == I2O_IOP_STATE_READY) { - /* allocate a message frame from Inbound queue */ - mp = (i2o_exec_sys_enable_message_t *)iop_msg_alloc(iop); - if (mp == NULL) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_create_systab: trans_msg_alloc failed")); - goto cleanup; - } - - /* Construct the ExecSysEanble message. */ - init_std_msghdr(iop, &mp->StdMessageFrame, 0x0, 0, - sizeof (i2o_exec_sys_enable_message_t), I2O_EXEC_SYS_ENABLE); - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_message((uint32_t *)mp, "ExecSysEnable"); -#endif - - /* send the message to the IOP */ - (void) iop_msg_send(iop, (void *)mp); - - /* since interrupts are disabled, we poll for the reply message */ - rmp = iop_poll_reply_msg(iop); - if ((rmp == NULL) || (rmp->ReqStatus != I2O_REPLY_STATUS_SUCCESS)) { -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_reply_message(iop, rmp); -#endif - if (rmp) - iop_msg_free(iop, rmp); - goto cleanup; - } - - /* paranoia? */ - ASSERT(get_msg_Function((i2o_message_frame_t *)rmp, - iop->ob_msg_queue.acc_hdl) == I2O_EXEC_SYS_ENABLE); - - iop_msg_free(iop, rmp); /* free up the reply message buffer */ - - /* get the IOP state now; it should be in OPERATIONAL state */ - if (i2o_get_iop_status(iop) == FAILURE) - goto cleanup; - } - - return (SUCCESS); - -cleanup: - return (FAILURE); -} - -/* - * Send an ExecIopReset message. This function is called from the - * i2o_msg_iop_init() with interrupts disabled. - */ -static int -i2o_send_exec_iop_reset(iop_instance_t *iop) -{ - ddi_dma_handle_t dma_handle = NULL; - ddi_acc_handle_t acc_hdl; - i2o_exec_iop_reset_status_t *buf = NULL; - i2o_exec_iop_reset_message_t *rmsgp; - size_t real_length; - ddi_dma_cookie_t dma_cookie; - uint_t ncookies; - - /* allocate a DMA handle */ - if (ddi_dma_alloc_handle(iop->dip, &dma_attr_contig, DDI_DMA_SLEEP, - NULL, &dma_handle) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_send_exec_iop_reset: ddi_dma_alloc_handle failed")); - goto cleanup; - } - - /* - * Allocate a temporary buffer for the status word structure. - */ - if (ddi_dma_mem_alloc(dma_handle, - sizeof (i2o_exec_iop_reset_status_t), &i2o_dev_acc_attr, - DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, (caddr_t *)&buf, - &real_length, &acc_hdl) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_send_exec_iop_reset: ddi_dma_mem_alloc failed")); - goto cleanup; - } - - if (ddi_dma_addr_bind_handle(dma_handle, NULL, (caddr_t)buf, - real_length, DDI_DMA_READ | DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &dma_cookie, &ncookies) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_send_exec_iop_reset: cannot bind memory")); - goto cleanup; - } - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_send_exec_iop_reset: dma_bind (vaddr %p paddr %x length %x)", - (void *)buf, dma_cookie.dmac_address, (int)dma_cookie.dmac_size)); - - /* allocate a message frame from Inbound queue */ - rmsgp = (i2o_exec_iop_reset_message_t *)iop_msg_alloc(iop); - if (rmsgp == NULL) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_send_exec_iop_reset: trans_msg_alloc failed")); - (void) ddi_dma_unbind_handle(dma_handle); - goto cleanup; - } - - /* construct the ExecIopReset message */ - init_std_msghdr(iop, (i2o_message_frame_t *)rmsgp, 0x0, 0, - sizeof (i2o_exec_iop_reset_message_t), - I2O_EXEC_IOP_RESET); - ddi_put32(iop->nexus_trans->acc_handle, &rmsgp->StatusWordLowAddress, - dma_cookie.dmac_address); - ddi_put32(iop->nexus_trans->acc_handle, - &rmsgp->StatusWordHighAddress, 0); - buf->ResetStatus = 0; - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_message((uint32_t *)rmsgp, "ExecIopReset"); -#endif - - /* send the message to the IOP */ - (void) iop_msg_send(iop, (void *)rmsgp); - - /* poll on the status word for IN_PROGRESS state */ - while (buf->ResetStatus != I2O_EXEC_IOP_RESET_IN_PROGRESS) { - int mseconds = 60000; /* 60 seconds */ - - if (buf->ResetStatus == I2O_EXEC_IOP_RESET_REJECTED) - goto cleanup; - - if (--mseconds < 0) { - DEBUGF(I2O_DEBUG_DEBUG, - (CE_CONT, "iop_reset: timed out")); - goto cleanup; - } - - drv_usecwait(1000); /* wait for 1msec */ - - /* sync DMA memory */ - (void) ddi_dma_sync(dma_handle, 0, 1, DDI_DMA_SYNC_FORCPU); - } - - (void) ddi_dma_unbind_handle(dma_handle); - - ddi_dma_mem_free(&acc_hdl); - - ddi_dma_free_handle(&dma_handle); - - return (SUCCESS); - - /* - * Error return; free up the allocated resources and return NULL. - */ -cleanup: - if (buf != NULL) - ddi_dma_mem_free(&acc_hdl); - - if (dma_handle != NULL) - ddi_dma_free_handle(&dma_handle); - - return (FAILURE); -} - - -static int -i2o_get_lct(iop_instance_t *iop) -{ - size_t real_length; - ddi_dma_cookie_t dma_cookie; - uint_t ncookies; - i2o_exec_lct_notify_message_t *msgp; - i2o_single_reply_message_frame_t *rmp = NULL; - uint_t lct_size; - - /* allocate a DMA handle if necessary */ - if (iop->lct.dma_handle == NULL) { - if (ddi_dma_alloc_handle(iop->dip, &dma_attr_contig, DDI_DMA_SLEEP, - NULL, &iop->lct.dma_handle) != DDI_SUCCESS) { - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_lct: ddi_dma_alloc_handle failed")); - goto cleanup; - } - } - - lct_size = ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->ExpectedLCTSize); - /* - * Allocate the buffer for LCT and send ExecLctNotify message. - */ - if (iop->lct.bufp == NULL || (iop->lct.size < lct_size)) { - - /* free up any old buffer */ - if (iop->lct.bufp != NULL) { - ddi_dma_mem_free(&iop->lct.acc_hdl); - iop->lct.bufp = NULL; - } - - iop->lct.size = lct_size; - - /* allocate a new buffer for LCT */ - if (ddi_dma_mem_alloc(iop->lct.dma_handle, - iop->lct.size, &i2o_dev_acc_attr, DDI_DMA_CONSISTENT, - DDI_DMA_SLEEP, NULL, (caddr_t *)&iop->lct.bufp, - &real_length, &iop->lct.acc_hdl) != DDI_SUCCESS) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_lct: ddi_dma_mem_alloc failed")); - goto cleanup; - } - - bzero((caddr_t)iop->lct.bufp, real_length); - } - - if (ddi_dma_addr_bind_handle(iop->lct.dma_handle, NULL, - (caddr_t)iop->lct.bufp, iop->lct.size, - DDI_DMA_READ | DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &dma_cookie, &ncookies) != DDI_SUCCESS) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_lct: cannot bind memory")); - goto cleanup; - } - - ASSERT(ncookies == 1); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_lct: dma_bind (vaddr %p paddr %x length %x)", - (void *)iop->lct.bufp, dma_cookie.dmac_address, - (int)dma_cookie.dmac_size)); - - /* allocate a message frame from Inbound queue */ - msgp = (i2o_exec_lct_notify_message_t *)iop_msg_alloc(iop); - if (msgp == NULL) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_get_lct: trans_msg_alloc failed")); - (void) ddi_dma_unbind_handle(iop->lct.dma_handle); - goto cleanup; - } - - /* - * Construct the ExecLctNotify message. - */ - init_std_msghdr(iop, &msgp->StdMessageFrame, 0x60, 0, - sizeof (i2o_exec_lct_notify_message_t), I2O_EXEC_LCT_NOTIFY); - msgp->ClassIdentifier = (uint32_t)0xFFFFFFFF; - msgp->LastReportedChangeIndicator = 0x0; - init_sgl_simple_ele(iop, msgp->SGL.u1.Simple, - I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER, - iop->lct.size, (uint_t)dma_cookie.dmac_address); - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_message((uint32_t *)msgp, "ExecLctNotify"); -#endif - - /* send the message to the IOP */ - (void) iop_msg_send(iop, (void *)msgp); - - /* since interrupts are disabled, we poll for the reply message */ - rmp = iop_poll_reply_msg(iop); - if ((rmp == NULL) || (rmp->ReqStatus != I2O_REPLY_STATUS_SUCCESS)) { - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_reply_message(iop, rmp); -#endif - if (rmp) - iop_msg_free(iop, rmp); - (void) ddi_dma_unbind_handle(iop->lct.dma_handle); - goto cleanup; - } - - /* paranoia? */ - ASSERT(get_msg_Function((i2o_message_frame_t *)rmp, - iop->ob_msg_queue.acc_hdl) == I2O_EXEC_LCT_NOTIFY); - - /* free up the reply message buffer */ - iop_msg_free(iop, rmp); - - (void) ddi_dma_unbind_handle(iop->lct.dma_handle); - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_LCT) - dump_lct(iop); -#endif - - return (SUCCESS); - - /* - * Error return; free up the allocated resources and return NULL. - */ -cleanup: - - if (iop->lct.bufp != NULL) { - ddi_dma_mem_free(&iop->lct.acc_hdl); - iop->lct.bufp = NULL; - } - - if (iop->lct.dma_handle != NULL) { - ddi_dma_free_handle(&iop->lct.dma_handle); - iop->lct.dma_handle = NULL; - } - - return (FAILURE); -} - -#define EXEC_CLASS_EVENT_MASK \ - (I2O_EVENT_IND_RESOURCE_LIMIT | I2O_EVENT_IND_CONNECTION_FAIL | \ - I2O_EVENT_IND_ADAPTER_FAULT | I2O_EVENT_IND_POWER_FAIL | \ - I2O_EVENT_IND_RESET_PENDING | I2O_EVENT_IND_RESET_IMMINENT | \ - I2O_EVENT_IND_HARDWARE_FAIL | I2O_EVENT_IND_XCT_CHANGE | \ - I2O_EVENT_IND_NEW_LCT_ENTRY | I2O_EVENT_IND_MODIFIED_LCT | \ - I2O_EVENT_IND_DDM_AVAILABILITY) - -/* - * Register Executive Class events to get notified by the IOP when - * any of these events occur. - * - * Assumpition: IOP interrupts are disabled. - */ -static int -i2o_iop_event_register(iop_instance_t *iop) -{ - i2o_util_event_register_message_t *msgp; - - /* allocate a message frame from Inbound queue */ - msgp = (i2o_util_event_register_message_t *)iop_msg_alloc(iop); - if (msgp == NULL) { - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_iop_event_register: trans_msg_alloc failed")); - return (FAILURE); - } - - /* - * Construct the UtilEventRegister message. There is no reply - * to this message until one of the specified events occurs. - */ - init_std_msghdr(iop, &msgp->StdMessageFrame, 0x0, 0, - sizeof (i2o_util_event_register_message_t), - I2O_UTIL_EVENT_REGISTER); - ddi_put32(iop->nexus_trans->acc_handle, - &msgp->TransactionContext, (uint32_t)(uintptr_t)iop); - ddi_put32(iop->nexus_trans->acc_handle, - (uint32_t *)&msgp->StdMessageFrame.InitiatorContext. - initiator_context_32bits, (uint32_t)i2o_msg_iop_event_reply); - /* Fow now, specify only the Executive Class events and */ - /* Config Dialog request event */ - ddi_put32(iop->nexus_trans->acc_handle, &msgp->EventMask, - EXEC_CLASS_EVENT_MASK | I2O_EVENT_IND_CONFIGURATION_FLAG); - - iop->event_mask = EXEC_CLASS_EVENT_MASK; - -#ifdef I2O_DEBUG - if (i2o_debug & I2O_DEBUG_MSG) - dump_message((uint32_t *)msgp, "UtilEventRegister"); -#endif - - /* send the message to the IOP */ - (void) iop_msg_send(iop, (void *)msgp); - - return (SUCCESS); -} - -/* - * called by the I2O nexus driver from i2o_create_devinfo(). - */ -void -i2o_msg_get_lct_info(i2o_iop_handle_t *handlep, i2o_lct_t **lctp, - ddi_acc_handle_t *acc_handlep) -{ - iop_instance_t *iop = ((i2o_iop_impl_hdl_t *)handlep)->iop; - - if (lctp) - *lctp = iop->lct.bufp; - - if (acc_handlep) - *acc_handlep = iop->lct.acc_hdl; -} - - -/* - * ************************************************************************ - * *** Reply Message Processing functions *** - * ************************************************************************ - */ - -/* - * Call back function to process the Executive Class event notification - * messages. - * - * For now, we process only the MODIFY_LCT event to update the local - * copy of the LCT. For other events we simply print the event information - * and ignore it. XXX FIX IT WHEN NEEDED XXX - */ -static void -i2o_msg_iop_event_reply(void *p, ddi_acc_handle_t acc_hdl) -{ - i2o_util_event_register_reply_t *msgp; - iop_instance_t *iop; - uint32_t event_indicator; - i2o_hrt_entry_t *hrt_entp; - i2o_lct_entry_t *lct_entp; - i2o_lct_entry_t *lp; - uint_t tid; - int i, n; - uint32_t event_data; - - msgp = (i2o_util_event_register_reply_t *)p; - iop = (iop_instance_t *) - (uintptr_t)ddi_get32(acc_hdl, &msgp->TransactionContext); - event_indicator = ddi_get32(acc_hdl, &msgp->EventIndicator); - - switch (event_indicator) { - - case I2O_EVENT_IND_ADAPTER_FAULT: - hrt_entp = (i2o_hrt_entry_t *)msgp->EventData; - cmn_err(CE_CONT, - "^Received ADAPTER_FAULT event from the IOP %x", - iop->iop_id); - cmn_err(CE_CONT, "^\tAdapterID: %x\n", ddi_get32(acc_hdl, - &hrt_entp->AdapterID)); - cmn_err(CE_CONT, "^\tControllingTID: %x\n", - get_hrt_entry_ControllingTID(hrt_entp, acc_hdl)); - cmn_err(CE_CONT, "^\tAdapterState: %x\n", - get_hrt_entry_AdapterState(hrt_entp, acc_hdl)); - cmn_err(CE_CONT, "^\tBusType: %x\n", hrt_entp->BusType); - cmn_err(CE_CONT, "^\tBusNumber: %x\n", hrt_entp->BusNumber); - break; - - case I2O_EVENT_IND_CONNECTION_FAIL: - cmn_err(CE_CONT, - "^Received CONNECTION_FAIL event from the IOP %x", - iop->iop_id); - break; - - case I2O_EVENT_IND_DDM_AVAILABILITY: - cmn_err(CE_CONT, - "^Received DDM_AVAILABILITY event from the IOP %x", - iop->iop_id); - event_data = ddi_get32(acc_hdl, msgp->EventData); - cmn_err(CE_CONT, "^\tTID %x Error Code %x", event_data & 0xFFF, - (event_data >> 12) & 0xF); - break; - - case I2O_EVENT_IND_HARDWARE_FAIL: - cmn_err(CE_CONT, - "^Received HARDWARE_FAIL event from the IOP %x", - iop->iop_id); - event_data = ddi_get32(acc_hdl, msgp->EventData); - cmn_err(CE_CONT, "^\tError Code %x", event_data); - break; - - case I2O_EVENT_IND_MODIFIED_LCT: - /* - * LCT entry is modified. Need to update the local - * copy of the LCT. - */ - - lct_entp = (i2o_lct_entry_t *)msgp->EventData; - tid = get_lct_entry_LocalTID(lct_entp, acc_hdl); - - /* - * locate the entry in the local copy of the LCT that - * matches the TID that has changed. And update the entry. - */ - mutex_enter(&iop->lct.lct_mutex); - - lp = iop->lct.bufp->LCTEntry; - n = ((ddi_get16(iop->lct.acc_hdl, &iop->lct.bufp->TableSize) << - 2) - sizeof (i2o_lct_t) + sizeof (i2o_lct_entry_t)) / - sizeof (i2o_lct_entry_t); - - for (i = 0; i < n; i++) { - if (tid == get_lct_entry_LocalTID(&lp[i], iop->lct.acc_hdl)) - break; - } - - ASSERT(i < n); - - /* copy the modified entry */ - lp[i] = *lct_entp; - - mutex_exit(&iop->lct.lct_mutex); - -#ifdef I2O_DEBUG - cmn_err(CE_CONT, "!Received MODIFY_LCT event from the IOP %x", - iop->iop_id); - cmn_err(CE_CONT, "!\tLocalTID: %x\n", - get_lct_entry_LocalTID(lct_entp, acc_hdl)); - cmn_err(CE_CONT, "!\tDeviceFlags: %x\n", - ddi_get32(acc_hdl, &lct_entp->DeviceFlags)); - cmn_err(CE_CONT, "!\tChangeIndicator: %x\n", - ddi_get32(acc_hdl, &lct_entp->ChangeIndicator)); - cmn_err(CE_CONT, "!\tClass: %x\n", - get_lct_entry_Class(lct_entp, acc_hdl)); - cmn_err(CE_CONT, "!\tSubClassInfo: %x\n", - ddi_get32(acc_hdl, &lct_entp->SubClassInfo)); - cmn_err(CE_CONT, "!\tParentTID: %x\n", - get_lct_entry_ParentTID(lct_entp, acc_hdl)); - cmn_err(CE_CONT, "!\tUserTID: %x\n", - get_lct_entry_UserTID(lct_entp, acc_hdl)); - cmn_err(CE_CONT, "!\tEventCapabilities: %x\n", - ddi_get32(acc_hdl, &lct_entp->EventCapabilities)); -#endif - break; - - case I2O_EVENT_IND_NEW_LCT_ENTRY: - cmn_err(CE_CONT, - "^Received NEW_LCT_ENTRY event from the IOP %x", - iop->iop_id); - lct_entp = (i2o_lct_entry_t *)msgp->EventData; - cmn_err(CE_CONT, "^\tLocalTID: %x\n", - get_lct_entry_LocalTID(lct_entp, acc_hdl)); - cmn_err(CE_CONT, "^\tDeviceFlags: %x\n", - ddi_get32(acc_hdl, &lct_entp->DeviceFlags)); - cmn_err(CE_CONT, "^\tChangeIndicator: %x\n", - ddi_get32(acc_hdl, &lct_entp->ChangeIndicator)); - cmn_err(CE_CONT, "^\tClass: %x\n", - get_lct_entry_Class(lct_entp, acc_hdl)); - cmn_err(CE_CONT, "^\tSubClassInfo: %x\n", - ddi_get32(acc_hdl, &lct_entp->SubClassInfo)); - cmn_err(CE_CONT, "^\tParentTID: %x\n", - get_lct_entry_ParentTID(lct_entp, acc_hdl)); - cmn_err(CE_CONT, "^\tUserTID: %x\n", - get_lct_entry_UserTID(lct_entp, acc_hdl)); - cmn_err(CE_CONT, "^\tEventCapabilities: %x\n", - ddi_get32(acc_hdl, &lct_entp->EventCapabilities)); - break; - - case I2O_EVENT_IND_POWER_FAIL: - cmn_err(CE_CONT, "^Received POWER_FAIL event from the IOP %x", - iop->iop_id); - break; - - case I2O_EVENT_IND_RESOURCE_LIMIT: - cmn_err(CE_CONT, - "^Received RESOURCE_LIMITS event from the IOP %x", - iop->iop_id); - event_data = ddi_get32(acc_hdl, msgp->EventData); - cmn_err(CE_CONT, "^\tError Code %x", event_data); - break; - - case I2O_EVENT_IND_XCT_CHANGE: - cmn_err(CE_CONT, "^Received XCT_CHANGE event from the IOP %x", - iop->iop_id); - break; - - case I2O_EVENT_IND_RESET_IMMINENT: - cmn_err(CE_CONT, - "^Received RESET_IMMINENT event from the IOP %x", - iop->iop_id); - break; - - case I2O_EVENT_IND_RESET_PENDING: - cmn_err(CE_CONT, - "^Received RESET_PENDING event from the IOP %x", - iop->iop_id); - break; - - case I2O_EVENT_IND_CONFIGURATION_FLAG: - cmn_err(CE_CONT, - "^Received CONFIGURATION_FLAG event from the IOP %x", - iop->iop_id); - break; - } -} - -/* - * Common reply message processing function: It simply copies the status - * code and sets the done_flag in the tcontext structure. - */ -static void -i2o_msg_common_reply(void *p, ddi_acc_handle_t acc_hdl) -{ - tcontext_t *tp; - - tp = (tcontext_t *)(uintptr_t)ddi_get32(acc_hdl, - &((i2o_single_reply_message_frame_t *)p)->TransactionContext); - - mutex_enter(&tp->cv_mutex); - tp->status = (int)((i2o_single_reply_message_frame_t *)p)->ReqStatus; - tp->done_flag = 1; - cv_broadcast(&tp->cv); - mutex_exit(&tp->cv_mutex); -} - -/* - * ************************************************************************ - * *** Implementation of OSM interfaces (PSARC: 1997/173) *** - * ************************************************************************ - */ - -/* - * Register the OSM for the specified I2O device. - * - * Implementation: The simplest implementation is to use the TID of - * the I2O device as the key to avoid multiple registrations. Since - * the max number of TIDs allocated is not big (< 32) we can simply - * maintain an array and use TID as the index. From the dip we need - * to find the IOP that this device belongs to. Currently, we do - * this by looking into the ioplist that matches with the devinfo - * node pointer of the parent for this device. - */ -int -i2o_msg_osm_register(dev_info_t *dip, i2o_iop_handle_t *handlep) -{ - uint_t tid; - dev_info_t *pdip; - iop_instance_t *iop; - i2o_iop_impl_hdl_t *hdl; - - /* get the TID for this device */ - tid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, - DDI_PROP_DONTPASS, "i2o-device-id", -1); - if (tid == (uint_t)-1) - return (DDI_FAILURE); - - /* - * Find the IOP that matches the parent of this device. - */ - pdip = ddi_get_parent(dip); - mutex_enter(&i2o_mutex); - for (iop = ioplist; iop; iop = iop->next) { - if (iop->dip == pdip) - break; - } - mutex_exit(&i2o_mutex); - - if (iop == NULL) - return (DDI_FAILURE); - - mutex_enter(&iop->osm_registry.osm_mutex); - - ASSERT(tid <= iop->osm_registry.max_tid); - - hdl = &iop->osm_registry.iop_handle_tab[tid]; - - /* verify that the device is not already registerd. */ - if (hdl->dip != NULL) { - mutex_exit(&iop->osm_registry.osm_mutex); - return (DDI_FAILURE); - } - - hdl->dip = dip; - hdl->iop = iop; - hdl->tid = tid; - - mutex_exit(&iop->osm_registry.osm_mutex); - - *handlep = (i2o_iop_handle_t *)hdl; - - return (DDI_SUCCESS); -} - -void -i2o_msg_osm_unregister(i2o_iop_handle_t *handlep) -{ - iop_instance_t *iop; - i2o_iop_impl_hdl_t *hdl = *(i2o_iop_impl_hdl_t **)handlep; - - iop = hdl->iop; - - ASSERT(hdl->tid <= iop->osm_registry.max_tid); - - mutex_enter(&iop->osm_registry.osm_mutex); - - hdl->dip = NULL; - hdl->iop = NULL; - hdl->tid = NULL; - - mutex_exit(&iop->osm_registry.osm_mutex); - - *handlep = NULL; -} - -/* - * Allocate a message frame for sending an I2O request message. - * - * Description: We allocate a system memory buffer so that the caller - * can take his own time to prepare the message. When the caller - * calls i2o_msg_send() then we allocate the real message frame - * from the inbound queue and free up the system memory buffer - * after copying the data. - */ -int -i2o_msg_alloc(i2o_iop_handle_t iop_hdl, int (*waitfp)(caddr_t), - caddr_t arg, void **msgp, i2o_msg_handle_t *msg_handlep, - ddi_acc_handle_t *acc_handlep) -{ - iop_instance_t *iop = ((i2o_iop_impl_hdl_t *)iop_hdl)->iop; - i2o_msg_impl_hdl_t *hdl; - ddi_acc_handle_t acc_hdl; - ddi_dma_handle_t dma_handle; - caddr_t buf; - size_t real_length; - size_t size; - - /* - * Allocate the message frame buffer from the system memory. - * - * Note: - * For now, the allocation is done by directly calling - * the DDI framework. Later this should be fixed to allocate - * it from a local pool for performance reasons. - */ - - if (ddi_dma_alloc_handle(iop->dip, &dma_attr_contig, waitfp, - arg, &dma_handle) != DDI_SUCCESS) - return (DDI_FAILURE); - - /* size of the buffer includes the i2o_msg_impl_hdl_t structure */ - size = iop->ib_msg_frame_size + sizeof (i2o_msg_impl_hdl_t); - - if (ddi_dma_mem_alloc(dma_handle, size, &i2o_dev_acc_attr, - DDI_DMA_CONSISTENT, waitfp, arg, &buf, - &real_length, &acc_hdl) != DDI_SUCCESS) { - - ddi_dma_free_handle(&dma_handle); - return (DDI_FAILURE); - } - - hdl = (i2o_msg_impl_hdl_t *)buf; - hdl->dma_handle = dma_handle; - hdl->acc_hdl = acc_hdl; - hdl->msgp = (void *)(buf + sizeof (i2o_msg_impl_hdl_t)); - - /* set the message size field in the message header */ - ddi_put16(hdl->acc_hdl, - &((i2o_message_frame_t *)(hdl->msgp))->MessageSize, - iop->ib_msg_frame_size >> 2); - - *msg_handlep = (i2o_msg_handle_t *)hdl; - *acc_handlep = acc_hdl; - *msgp = hdl->msgp; - - return (DDI_SUCCESS); -} - - -/* - * Send the I2O message to the IOP. - * - * Description: We need to do the following. - * 1. If the inbound message queue freelist is empty (i.e no - * valid mfa available) then queue up this request for - * the i2o_msg_send_process() thread and return DDI_SUCCESS. - * 2. We have a valid mfa. Copy the data from the system memory - * message buffer into the real message frame and send the - * message. - * 3. Free up the system memory message buffer. - * - * Note: - * For now, we return the system memory buffer back to the DDI - * framework. Fix this later to put the buffer into the local pool - * for better performance. - */ -int -i2o_msg_send(i2o_iop_handle_t iop_hdl, void *msg, i2o_msg_handle_t msg_hdl) -{ - uint32_t mfa; - iop_instance_t *iop = ((i2o_iop_impl_hdl_t *)iop_hdl)->iop; - i2o_msg_impl_hdl_t *hdl = (i2o_msg_impl_hdl_t *)msg_hdl; - i2o_message_frame_t *real_msgp; - size_t msg_size; - ddi_acc_handle_t acc_hdl; - ddi_dma_handle_t dma_handle; - - ASSERT(hdl->msgp == msg); - - mutex_enter(&iop->iop_ib_mutex); - - /* get a valid mfa from the inbound message freelist FIFO */ - - mfa = (* iop->nexus_trans->i2o_trans_msg_alloc) - (iop->nexus_trans->nexus_handle); - - if (mfa == (uint_t)0xFFFFFFFF) { - /* - * No valid MFA available. Queue up the request. - */ - if (iop->send_queue_head == NULL) { - iop->send_queue_head = iop->send_queue_tail = hdl; - hdl->next = NULL; - } else { - hdl->next = NULL; - iop->send_queue_tail->next = hdl; - iop->send_queue_tail = hdl; - } - - if (iop->iop_flags & IOP_SEND_QUEUE_PROC_RUNNING) - /* wakeup the i2o_msg_send_proc() */ - cv_broadcast(&iop->send_queue_cv); - else { - /* - * Create the i2o_msg_send_proc() thread and - * run it. - */ - cv_init(&iop->send_queue_cv, NULL, CV_DEFAULT, NULL); - (void) thread_create(NULL, 0, i2o_msg_send_proc, - iop, 0, &p0, TS_RUN, minclsyspri); - iop->iop_flags |= IOP_SEND_QUEUE_PROC_RUNNING; - } - - iop->send_queue_count++; - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, "i2o_msg_send: req queued")); - - mutex_exit(&iop->iop_ib_mutex); - - return (DDI_SUCCESS); - } - - mutex_exit(&iop->iop_ib_mutex); - - real_msgp = (i2o_message_frame_t *) - (mfa + iop->nexus_trans->iop_base_addr); - - /* - * Copy the message to the real message frame. - */ - msg_size = ddi_get16(hdl->acc_hdl, - &((i2o_message_frame_t *)msg)->MessageSize) << 2; - ASSERT(msg_size <= iop->ib_msg_frame_size); - bcopy(msg, (void *)real_msgp, msg_size); - - /* send the message to the IOP */ - (void) (* iop->nexus_trans->i2o_trans_msg_send) - (iop->nexus_trans->nexus_handle, - (caddr_t)(real_msgp) - iop->nexus_trans->iop_base_addr); - - /* - * Now, free up the system resources allocated for this message - */ - acc_hdl = hdl->acc_hdl; - dma_handle = hdl->dma_handle; - ddi_dma_mem_free(&acc_hdl); - ddi_dma_free_handle(&dma_handle); - - return (DDI_SUCCESS); -} - -/* - * Copy the LCT contents to the specified buffer. - */ -int -i2o_msg_get_lct(i2o_iop_handle_t iop_hdl, void *buf, size_t buf_size, - size_t *lct_sizep, size_t *real_sizep) -{ - iop_instance_t *iop = ((i2o_iop_impl_hdl_t *)iop_hdl)->iop; - size_t copy_size; - - mutex_enter(&iop->lct.lct_mutex); - - if (lct_sizep != NULL) - *lct_sizep = iop->lct.size; - - if (buf == NULL) - copy_size = 0; - else { - copy_size = min(buf_size, iop->lct.size); - bcopy((void *)iop->lct.bufp, buf, copy_size); - } - - if (real_sizep) - *real_sizep = copy_size; - - mutex_exit(&iop->lct.lct_mutex); - - return (DDI_SUCCESS); -} - -/* - * Process the reply message queue. This routine is called at the time of - * IOP hw interrupt. Current implementation is a simple while loop which - * reads the outbound postlist FIFO and if the MFA is a valid MFA - * (i.e MFA != 0xFFFFFFFF) then it calls the callback function in the - * InitiatorContext field of the message. - */ -void -i2o_msg_process_reply_queue(i2o_iop_handle_t handle) -{ - uint32_t mfa; - iop_instance_t *iop = ((i2o_iop_impl_hdl_t *)handle)->iop; - void (* initiator_context)(); - i2o_single_reply_message_frame_t *rmp; - - mutex_enter(&iop->iop_ob_mutex); - - mfa = (* iop->nexus_trans->i2o_trans_msg_recv) - (iop->nexus_trans->nexus_handle); - - /* - * WORKAROUND for i960 chip bug. It seems that sometimes the i960 - * is dropping the write request when IxWorks writes the MFA to - * the FIFO before generating the interrupt. As a workaround, IxWorks - * writes 0xFFFFFFFF first and then correct MFA. Two successive - * reads to the postlist FIFO should confirm if the FIFO is - * really empty. In the absence of reading the FIFO second time - * results in another call to IOP interrupt service routine. - * For better performance we do the second read of FIFO here. - */ - if (mfa == (uint_t)0xFFFFFFFF) { - /* read the FIFO again */ - mfa = (* iop->nexus_trans->i2o_trans_msg_recv) - (iop->nexus_trans->nexus_handle); - } - - while (mfa != (uint_t)0xFFFFFFFF) { - - rmp = (i2o_single_reply_message_frame_t *) - ((mfa - iop->ob_msg_queue.base_paddr) + - iop->ob_msg_queue.base_addr); - - initiator_context = (void (*)()) - (uintptr_t)ddi_get32(iop->ob_msg_queue.acc_hdl, - (uint32_t *)&rmp->StdMessageFrame.InitiatorContext); - - /* - * Check for NULL Initiator Context field. If it is NULL - * (should not happen) then ignore the message. - */ - if (initiator_context == NULL) { - cmn_err(CE_WARN, "I2O: No Initiator Context in the MSG" - " (Function: 0x%x Transaction Context: 0x%x" - " TID: 0x%x) - reply msg ignored", - get_msg_Function((i2o_message_frame_t *)rmp, - iop->ob_msg_queue.acc_hdl), - ddi_get32(iop->ob_msg_queue.acc_hdl, - (uint32_t *)&rmp->TransactionContext), - get_msg_TargetAddress((i2o_message_frame_t *)rmp, - iop->ob_msg_queue.acc_hdl)); - } else { - - /* - * We need to do the DMA sync for the message frame - * because the reply message buffers are allocated - * from the system memory and the IOP does DMA to - * write to this memory. - */ - (void) ddi_dma_sync(iop->ob_msg_queue.dma_handle, - (off_t)(mfa - iop->ob_msg_queue.base_paddr), - (size_t)iop->ob_msg_queue.framesize, - DDI_DMA_SYNC_FORCPU); - - /* - * Call the callback function of the OSM to process - * the message. - */ - (* initiator_context)((void *)rmp, - iop->ob_msg_queue.acc_hdl); - - } - - /* Now, putback the MFA into the outbound freelist FIFO */ - (* iop->nexus_trans->i2o_trans_msg_freebuf) - (iop->nexus_trans->nexus_handle, mfa); - - /* get the next MFA from the FIFO */ - mfa = (* iop->nexus_trans->i2o_trans_msg_recv) - (iop->nexus_trans->nexus_handle); - } - - mutex_exit(&iop->iop_ob_mutex); -} - -/* - * Process the I2O request message queue. The request messages are - * queued up for this IOP because there was no free mfa available - * from the inbound freelist. Currently, there is no mechanism - * where IOP can inform the host when the freelist is not empty. - * So, we just have to poll on the inbound message queue fifo until - * we find a valid frame. But, starvation on the inbound MFAs should - * not happen with the current implementations of IRTOS where the - * IRTOS copies the message into local buffer and puts the MFA back - * on the freelist immediately. So, this code may never get executed - * in practice! - * - */ -static void -i2o_msg_send_proc(iop_instance_t *iop) -{ - uint32_t mfa; - i2o_message_frame_t *real_msgp; - size_t msg_size; - ddi_acc_handle_t acc_hdl; - ddi_dma_handle_t dma_handle; - i2o_msg_impl_hdl_t *q; - - mutex_enter(&iop->iop_ib_mutex); - - for (;;) { - - q = iop->send_queue_head; /* head of the queue */ - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, "i2o_msg_send_proc: called")); - - while (q != NULL) { - - ASSERT((iop->iop_flags & IOP_IS_IN_UNINIT) != 0); - - /* - * get a valid mfa from the inbound message - * freelist FIFO - */ - - mfa = (* iop->nexus_trans->i2o_trans_msg_alloc) - (iop->nexus_trans->nexus_handle); - - if (mfa == (uint_t)0xFFFFFFFF) { - /* - * No valid MFA available. Wait for a while - * and try again. - */ - delay(1); - continue; /* try again */ - } - - real_msgp = (i2o_message_frame_t *) - (mfa + iop->nexus_trans->iop_base_addr); - - /* Copy the message to the real message frame */ - msg_size = 4 * ddi_get16(q->acc_hdl, - &((i2o_message_frame_t *)(q->msgp))->MessageSize); - ASSERT(msg_size <= iop->ib_msg_frame_size); - bcopy(q->msgp, (void *)real_msgp, msg_size); - - - /* send the message to the IOP */ - (void) (* iop->nexus_trans->i2o_trans_msg_send) - (iop->nexus_trans->nexus_handle, - (caddr_t)(real_msgp) - - iop->nexus_trans->iop_base_addr); - - /* free up the associated system resources */ - acc_hdl = q->acc_hdl; - dma_handle = q->dma_handle; - q = q->next; - ddi_dma_mem_free(&acc_hdl); - ddi_dma_free_handle(&dma_handle); - } - - iop->send_queue_head = NULL; - iop->send_queue_tail = NULL; - - /* if the IOP is being uninitialized then exit */ - - if (iop->iop_flags & IOP_IS_IN_UNINIT) { - iop->iop_flags &= ~IOP_SEND_QUEUE_PROC_RUNNING; - - thread_exit(); - - DEBUGF(I2O_DEBUG_DEBUG, (CE_CONT, - "i2o_msg_send_proc: exit...")); - } - - /* otherwise, wait for the wakeup call from i2o_msg_send() */ - cv_wait(&iop->send_queue_cv, &iop->iop_ib_mutex); - } -} - -/* - * ************************************************************************ - * *** Functions used for Debugging only *** - * ************************************************************************ - */ - -#ifdef I2O_DEBUG - -static void -dump_iop_status_buf(iop_instance_t *iop) -{ - int i; - uint32_t *p = (uint32_t *)iop->status.bufp; - - cmn_err(CE_CONT, "?IOP Status Block: "); - for (i = 0; i < sizeof (i2o_exec_status_get_reply_t); i += 4) - cmn_err(CE_CONT, "0x%x", *p++); - cmn_err(CE_CONT, - "?\tOrganizationID: %x\n", ddi_get16(iop->status.acc_hdl, - &iop->status.bufp->OrganizationID)); - cmn_err(CE_CONT, "?\tIOP_ID: %x\n", - get_i2o_exec_status_reply_IOP_ID(iop->status.bufp, - iop->status.acc_hdl)); - cmn_err(CE_CONT, "?\tHostUnitID: %x\n", ddi_get16(iop->status.acc_hdl, - &iop->status.bufp->HostUnitID)); - cmn_err(CE_CONT, "?\tI2oVersion: %x\n", - get_i2o_exec_status_reply_I2oVersion(iop->status.bufp, - iop->status.acc_hdl)); - cmn_err(CE_CONT, "?\tSegmentNumber: %x\n", - get_i2o_exec_status_reply_SegmentNumber(iop->status.bufp, - iop->status.acc_hdl)); - cmn_err(CE_CONT, "?\tIopState: %x\n", ddi_get8(iop->status.acc_hdl, - &iop->status.bufp->IopState)); - cmn_err(CE_CONT, "?\tMessengerType: %x\n", ddi_get8(iop->status.acc_hdl, - &iop->status.bufp->MessengerType)); - cmn_err(CE_CONT, - "?\tInboundMFrameSize: %x\n", ddi_get16(iop->status.acc_hdl, - &iop->status.bufp->InboundMFrameSize)); - cmn_err(CE_CONT, "?\tInitCode: %x\n", ddi_get8(iop->status.acc_hdl, - &iop->status.bufp->InitCode)); - cmn_err(CE_CONT, - "?\tMaxInboundMFrames: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->MaxInboundMFrames)); - cmn_err(CE_CONT, - "?\tCurrentInboundMFrames: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->CurrentInboundMFrames)); - cmn_err(CE_CONT, - "?\tMaxOutboundMFrames: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->MaxOutboundMFrames)); - cmn_err(CE_CONT, - "?\tProductIDString: %s\n", iop->status.bufp->ProductIDString); - cmn_err(CE_CONT, - "?\tExpectedLCTSize: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->ExpectedLCTSize)); - cmn_err(CE_CONT, - "?\tIopCapabilities: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->IopCapabilities)); - cmn_err(CE_CONT, - "?\tDesiredPrivateMemSize: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->DesiredPrivateMemSize)); - cmn_err(CE_CONT, - "?\tCurrentPrivateMemSize: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->CurrentPrivateMemSize)); - cmn_err(CE_CONT, - "?\tCurrentPrivateMemBase: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->CurrentPrivateMemBase)); - cmn_err(CE_CONT, - "?\tDesiredPrivateIOSize: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->DesiredPrivateIOSize)); - cmn_err(CE_CONT, - "?\tCurrentPrivateIOSize: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->CurrentPrivateIOSize)); - cmn_err(CE_CONT, - "?\tCurrentPrivateIOBase: %x\n", ddi_get32(iop->status.acc_hdl, - &iop->status.bufp->CurrentPrivateIOBase)); -} - -static void -dump_hrt(iop_instance_t *iop) -{ - int i, n; - i2o_hrt_entry_t *entp; - uint32_t *p; - - n = ddi_get16(iop->hrt.acc_hdl, &iop->hrt.bufp->NumberEntries); - - entp = &iop->hrt.bufp->HRTEntry[0]; - - cmn_err(CE_CONT, - "?Hardware Resource Table (IOP_ID %x HRTVersion %x #ent %x):\n", - iop->iop_id, iop->hrt.bufp->HRTVersion, n); - - for (i = 0; i < n; i++, entp++) { - - p = (uint32_t *)entp; - - if (get_hrt_entry_AdapterState(entp, iop->hrt.acc_hdl) == 0) - continue; - - cmn_err(CE_CONT, "0x%x 0x%x 0x%x 0x%x", p[0], p[1], - p[2], p[3]); - cmn_err(CE_CONT, - "?\tAdapterID: %x\n", ddi_get32(iop->hrt.acc_hdl, - &entp->AdapterID)); - cmn_err(CE_CONT, "?\tControllingTID: %x\n", - get_hrt_entry_ControllingTID(entp, iop->hrt.acc_hdl)); - cmn_err(CE_CONT, "?\tAdapterState: %x\n", - get_hrt_entry_AdapterState(entp, iop->hrt.acc_hdl)); - cmn_err(CE_CONT, "?\tBusType: %x\n", entp->BusType); - cmn_err(CE_CONT, "?\tBusNumber: %x\n", entp->BusNumber); - - switch (entp->BusType) { - case I2O_PCI_BUS: - cmn_err(CE_CONT, "?\t\tPciFunctionNumber: %x", - entp->uBus.PCIBus.PciFunctionNumber); - cmn_err(CE_CONT, "?\t\tPciDeviceNumber: %x", - entp->uBus.PCIBus.PciDeviceNumber); - cmn_err(CE_CONT, "?\t\tPciBusNumber: %x", - entp->uBus.PCIBus.PciBusNumber); - cmn_err(CE_CONT, "?\t\tPciVendorID: %x", - entp->uBus.PCIBus.PciVendorID); - cmn_err(CE_CONT, "?\t\tPciDeviceID: %x", - entp->uBus.PCIBus.PciDeviceID); - break; - default: - break; - } - } -} - - -static void -dump_lct(iop_instance_t *iop) -{ - int i, j, n; - i2o_lct_entry_t *entp; - - n = (ddi_get16(iop->lct.acc_hdl, &iop->lct.bufp->TableSize) * 4) / - sizeof (i2o_lct_entry_t); - entp = &iop->lct.bufp->LCTEntry[0]; - - cmn_err(CE_CONT, "?Logical Config Table (IopFlags %x LctVer %x)\n", - ddi_get32(iop->lct.acc_hdl, &iop->lct.bufp->IopFlags), - get_lct_LctVer(iop->lct.bufp, iop->lct.acc_hdl)); - - for (i = 0; i < n; i++) { - cmn_err(CE_CONT, "?\tLocalTID: %x\n", - get_lct_entry_LocalTID(entp, iop->lct.acc_hdl)); - cmn_err(CE_CONT, "?\tDeviceFlags: %x\n", - ddi_get32(iop->lct.acc_hdl, &entp->DeviceFlags)); - cmn_err(CE_CONT, "?\tChangeIndicator: %x\n", - ddi_get32(iop->lct.acc_hdl, &entp->ChangeIndicator)); - cmn_err(CE_CONT, "?\tClass: %x\n", - get_lct_entry_Class(entp, iop->lct.acc_hdl)); - cmn_err(CE_CONT, "?\tVersion: %x\n", - get_lct_entry_Version(entp, iop->lct.acc_hdl)); - cmn_err(CE_CONT, "?\tOrganizationID: %x\n", - get_lct_entry_OrganizationID(entp, iop->lct.acc_hdl)); - cmn_err(CE_CONT, "?\tSubClassInfo: %x\n", - ddi_get32(iop->lct.acc_hdl, &entp->SubClassInfo)); - cmn_err(CE_CONT, "?\tBiosInfo: %x\n", - get_lct_entry_BiosInfo(entp, iop->lct.acc_hdl)); - cmn_err(CE_CONT, "?\tParentTID: %x\n", - get_lct_entry_ParentTID(entp, iop->lct.acc_hdl)); - cmn_err(CE_CONT, "?\tUserTID: %x\n", - get_lct_entry_UserTID(entp, iop->lct.acc_hdl)); - cmn_err(CE_CONT, "?\tEventCapabilities: %x\n", - ddi_get32(iop->lct.acc_hdl, &entp->EventCapabilities)); - cmn_err(CE_CONT, "?\tIdentityTag: "); - for (j = 0; j < 8; j++) - cmn_err(CE_CONT, "?\t%x ", entp->IdentityTag[j]); - cmn_err(CE_CONT, "?\n"); - - entp++; - } -} - - -static void -dump_message(uint32_t *mp, char *name) -{ - cmn_err(CE_CONT, "%s: MSGHDR(%p): %x %x %x %x", name, (void *)mp, mp[0], - mp[1], mp[2], mp[3]); - cmn_err(CE_CONT, "PAYLOAD(%p): %x %x %x %x %x %x", - (void *)&mp[4], mp[4], mp[5], mp[6], mp[7], mp[8], mp[9]); -} - -static void -dump_reply_message(iop_instance_t *iop, i2o_single_reply_message_frame_t *rmp) -{ - if (rmp == NULL) - return; - - cmn_err(CE_CONT, - "?Reply Message Frame (IOP %x Function %x):", iop->iop_id, - get_msg_Function(&rmp->StdMessageFrame, iop->ob_msg_queue.acc_hdl)); - cmn_err(CE_CONT, - "?\tReqStatus: %x DetailedStatusCode %x\n", rmp->ReqStatus, - ddi_get16(iop->ob_msg_queue.acc_hdl, &rmp->DetailedStatusCode)); -} - -#endif - - - -static uint_t -i2o_get_mem(dev_info_t *dip, uint_t len, uint_t *base) -{ - ndi_ra_request_t req; - uint64_t retlen; - uint64_t retbase; -#ifdef lint - dip = dip; -#endif - - bzero((caddr_t)&req, sizeof (req)); - - req.ra_addr = (uint64_t)*base; - if (*base != 0) - req.ra_flags |= NDI_RA_ALLOC_SPECIFIED; - req.ra_len = (uint64_t)len; - req.ra_boundbase = 0; - req.ra_boundlen = 0xffffffffUL; - req.ra_flags |= NDI_RA_ALLOC_BOUNDED; - - if (ndi_ra_alloc(ddi_root_node(), &req, &retbase, &retlen, - NDI_RA_TYPE_MEM, 0) == NDI_FAILURE) { - *base = 0; - return (0); - } else { - *base = retbase; - return (*base); - } -} - - -static void -i2o_return_mem(dev_info_t *dip, uint_t base, uint_t len) -{ -#ifdef lint - dip = dip; -#endif - (void) ndi_ra_free(ddi_root_node(), (uint64_t)base, (uint64_t)len, - NDI_RA_TYPE_MEM, 0); -} - - -static uint_t -i2o_get_io(dev_info_t *dip, uint_t len, uint_t *base) -{ - ndi_ra_request_t req; - uint64_t retbase, retlen; - -#ifdef lint - dip = dip; -#endif - bzero((caddr_t)&req, sizeof (req)); - if (*base != 0) - req.ra_flags |= NDI_RA_ALLOC_SPECIFIED; - req.ra_flags |= NDI_RA_ALIGN_SIZE; - req.ra_addr = (uint64_t)*base; - req.ra_boundbase = 0; - req.ra_boundlen = 0xffffffffUL; - req.ra_flags |= NDI_RA_ALLOC_BOUNDED; - req.ra_len = (uint64_t)len; - if (ndi_ra_alloc(ddi_root_node(), &req, &retbase, &retlen, - NDI_RA_TYPE_IO, 0) == NDI_FAILURE) { - *base = 0; - return (0); - } else { - *base = retbase; - return (*base); - } -} - -static void -i2o_return_io(dev_info_t *dip, uint_t base, uint_t len) -{ -#ifdef lint - dip = dip; -#endif - (void) ndi_ra_free(ddi_root_node(), (uint64_t)base, (uint64_t)len, - NDI_RA_TYPE_IO, 0); -} diff --git a/usr/src/uts/common/io/i2o/i2o_scsi.c b/usr/src/uts/common/io/i2o/i2o_scsi.c deleted file mode 100644 index b880390574..0000000000 --- a/usr/src/uts/common/io/i2o/i2o_scsi.c +++ /dev/null @@ -1,4440 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - - -/* - * I2O SCSI HBA OSM - * - * I2O Scsi Host Bus Adapter Operating System Module (OSM) - * conforms to I2O and converts SCSI pkt information send by - * the target driver through SCSA to I2O message format and send it - * down to the IOP. This driver utilized the I2O messaging framework, - * i2o_msg. Currently only support on x86. - * - */ - -/* - * debugging code - */ -#ifdef DEBUG -#define I2OHBA_DEBUG -#endif - -#ifdef I2OHBA_DEBUG -int i2ohbadebugflag = 0; -int ddi_dma_alloc_hdl = 0; -int ddi_dma_alloc_mem = 0; -int ddi_dma_bind_hdl = 0; -int ddi_dma_unbind = 0; -int ddi_dma_free_mem = 0; -int ddi_dma_bind_free = 0; -int ddi_dma_bufalloc = 0; -int ddi_dma_buf_bind = 0; -int ddi_dma_buf_unbind = 0; -int ddi_dma_buf_free_hdl = 0; -#define DEBUGF(level, args) \ - { if (i2ohbadebugflag >= (level)) cmn_err args; } -#else -#define DEBUGF(leve, args) /* nothing */ -#endif - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/varargs.h> -#include <sys/modctl.h> -#include <sys/scsi/scsi.h> -#include <sys/scsi/scsi_ctl.h> -#include <sys/scsi/impl/scsi_reset_notify.h> - -#include <sys/i2o/i2obscsi.h> -#include <sys/i2o/i2oadptr.h> -#include <sys/i2o/i2omsg.h> -#include <sys/i2o/i2outil.h> - -#include "i2o_scsi_var.h" -#include "i2o_scsi_util.h" -#include "i2o_scsi_cmd.h" - -/* - * dev_ops functions prototypes - */ -static int i2ohba_info(dev_info_t *dip, ddi_info_cmd_t infocmd, - void *arg, void **result); -static int i2ohba_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); -static int i2ohba_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); - -/* - * Function prototypes - * - * SCSA functions exported by means of the transport table - */ -static int i2ohba_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, - scsi_hba_tran_t *tran, struct scsi_device *sd); -static int i2ohba_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt); -static int i2ohba_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); -static int i2ohba_scsi_reset(struct scsi_address *ap, int level); -static int i2ohba_scsi_getcap(struct scsi_address *ap, char *cap, int whom); -static int i2ohba_scsi_setcap(struct scsi_address *ap, char *cap, int value, - int whom); -static struct scsi_pkt *i2ohba_scsi_init_pkt(struct scsi_address *ap, - struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, - int tgtlen, int flags, int (*callback)(), caddr_t arg); -static void i2ohba_scsi_destroy_pkt(struct scsi_address *ap, - struct scsi_pkt *pkt); -static void i2ohba_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt); -static void i2ohba_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt); -static int i2ohba_scsi_reset_notify(struct scsi_address *ap, int flag, - void (*callback)(caddr_t), caddr_t arg); - -/* - * i2ohba's complete function for sending the SCSI pkt. - */ -static void i2ohba_callback(i2o_message_frame_t *msg, ddi_acc_handle_t - acc_handle); - - -/* - * Internal Functions - */ -/* tid map to scsi convertion function */ -static int i2ohba_i_tid_to_scsi(dev_info_t *dip, struct i2ohba *i2ohba, - i2o_lct_t *lct_buf, size_t lct_real_size, - ddi_acc_handle_t lctbuf_dmaacchandle); - -/* capability/prop functions */ -static void i2ohba_i_updatesync(struct i2ohba *i2ohba, int tgt); -static void i2ohba_i_update_props(struct i2ohba *i2ohba, int tgt); -static void i2ohba_i_update_this_prop(struct i2ohba *i2ohba, char *property, - int value); -static void i2ohba_i_initcap(struct i2ohba *i2ohba); - -/* dma engine funcitons */ -static int i2ohba_i_dma_alloc(struct i2ohba *i2ohba, struct scsi_pkt *pkt, - struct buf *bp, int flags, int (*callback)()); -static int i2ohba_i_dma_move(struct i2ohba *i2ohba, struct scsi_pkt *pkt, - struct buf *bp); - -/* timer and recovery functions */ -static void i2ohba_i_watch(void *); -static void i2ohba_i_fatal_error(struct i2ohba *i2ohba); -static int i2ohba_i_reset_interface(struct i2ohba *i2ohba, int action); -static int i2ohba_i_reset_abort(struct i2ohba *i2ohba, uint16_t tid, int action, - struct i2ohba_cmd *cmd); - -/* command processing functions */ -static void i2ohba_i_polled_cmd_start(struct i2ohba *i2ohba, - struct i2ohba_cmd *sp); -static void i2ohba_i_req_insert(struct i2ohba *i2ohba, struct i2ohba_cmd *sp); -static void i2ohba_i_req_remove(struct i2ohba *i2ohba, struct i2ohba_cmd *sp); -static void i2ohba_i_pkt_comp(i2o_single_reply_message_frame_t *reply, - ddi_acc_handle_t acc_handle, struct i2ohba_cmd *sp); -static void i2ohba_i_handle_arq(i2o_scsi_error_reply_message_frame_t *replyerr, - struct i2ohba_cmd *sp, int aqcount); -static void i2ohba_i_qflush(struct i2ohba *i2ohba, uint16_t start_tgt, - uint16_t end_tgt); -/*PRINTFLIKE3*/ -static void i2ohba_i_log(struct i2ohba *i2ohba, int level, char *fmt, ...); -static void i2ohba_i_print_state(struct i2ohba *i2ohba); - -/* utility parameter functions */ -static int i2ohba_utilparamset_msg(struct i2ohba *i2ohba, int tgt, - uint16_t tid, uint16_t group, uint16_t idx, uint16_t value); -static int i2ohba_utilparamget_msg(struct i2ohba *i2ohba, uint16_t tidx, - char flag); -static void i2ohba_utilmsg_comp(i2o_message_frame_t *msg, ddi_acc_handle_t - acc_handle); -static int i2ohba_utilclaim_msg(struct i2ohba *i2ohba, uint16_t tid, - int action); - -/* - * mutex for protecting variables shared by all instances of the driver - */ -static kmutex_t i2ohba_log_mutex; - -/* - * Local static data - */ -static void *i2ohba_state = NULL; -static clock_t i2ohba_tick; /* watch interval in HZ */ -static clock_t i2ohba_watchdog_tick = 15; /* watch interval in sec */ -static int i2ohba_scsi_reset_delay = 3000; -ddi_device_acc_attr_t dev_attr; /* dev_attr */ -static char i2ohba_log_buf[256]; /* buffer used in i2ohba_i_log */ - - - -/* - * DMA Attribute for data buffers - */ -static ddi_dma_attr_t i2ohba_dma_attr = { - DMA_ATTR_VERSION, /* dma_attr_version */ - 0, /* dma_attr_addr_lo */ - 0xffffffffull, /* dma_attr_addr_hi */ - 0x00ffffffull, /* dma_attr_count_max */ - 1, /* dma_attr_align */ - 1, /* dma_attr_burstsizes */ - 1, /* dma_attr_minxfer */ - 0xffffffffull, /* dma_attr_maxxfer */ - 0x00ffffffull, /* dma_attr_seg */ - I2OHBA_CMD_NSEGS, /* dma_attr_sgllen */ - 512, /* dma_attr_granular */ - 0 /* dma_attr_flags */ -}; - -/* - * DMA attributes for SGL buffer - */ -static ddi_dma_attr_t i2ohba_dmasgl_attr = { - DMA_ATTR_VERSION, /* dma_attr_version */ - 0, /* dma_attr_addr_lo */ - 0xffffffffull, /* dma_attr_addr_hi */ - 0x00ffffffull, /* dma_attr_count_max */ - 1, /* dma_attr_align */ - 1, /* dma_attr_burstsizes */ - 1, /* dma_attr_minxfer */ - 0xffffffffull, /* dma_attr_maxxfer */ - 0x00ffffffull, /* dma_attr_seg */ - 0x1, /* dma_attr_sgllen */ - 1, /* dma_attr_granular */ - 0 /* dma_attr_flags */ -}; - -/* - * Hotplug support - * Leaf ops (hotplug controls for target devices) - * XXXLWXXX currently doesn't support any hotpluging - */ - -static struct cb_ops i2ohba_cb_ops = { - nodev, /* open */ - nodev, /* close */ - nodev, /* strategy */ - nodev, /* print */ - nodev, /* dump */ - nodev, /* read */ - nodev, /* write */ - nodev, /* ioctl */ - nodev, /* devmap */ - nodev, /* mmap */ - nodev, /* segmap */ - nochpoll, /* poll */ - ddi_prop_op, /* prop_op */ - NULL, - D_NEW | D_MP | D_HOTPLUG -}; - -/* - * autoconfiguration routines. - */ - -static struct dev_ops i2ohba_ops = { - DEVO_REV, /* rev, */ - 0, /* refcnt */ - i2ohba_info, /* getinfo */ - nulldev, /* identify */ - nulldev, /* probe */ - i2ohba_attach, /* attach */ - i2ohba_detach, /* detach */ - nodev, /* reset */ - &i2ohba_cb_ops, /* driver operations */ - NULL, /* bus ops */ - NULL /* power ops */ -}; - -char _depends_on[] = "misc/scsi misc/i2o_msg"; - -static struct modldrv modldrv = { - &mod_driverops, /* Type of module */ - "I2O SCSI HBA OSM version %I%", /* module name */ - &i2ohba_ops, /* driver ops */ - -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *)&modldrv, - NULL -}; - -int -_init(void) -{ - int ret; - - ret = ddi_soft_state_init(&i2ohba_state, sizeof (struct i2ohba), - I2OHBA_INITIAL_SOFT_SPACE); - - if (ret != 0) - return (ret); - - mutex_init(&i2ohba_log_mutex, NULL, MUTEX_DRIVER, NULL); - - i2ohba_tick = drv_usectohz(i2ohba_watchdog_tick * 1000000); - - if ((ret = scsi_hba_init(&modlinkage)) != 0) { - mutex_destroy(&i2ohba_log_mutex); - ddi_soft_state_fini(&i2ohba_state); - return (ret); - } - - if ((ret = mod_install(&modlinkage)) != 0) { - scsi_hba_fini(&modlinkage); - mutex_destroy(&i2ohba_log_mutex); - ddi_soft_state_fini(&i2ohba_state); - } - - return (ret); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - -int -_fini(void) -{ - - int ret; - - if ((ret = mod_remove(&modlinkage)) != 0) - return (ret); - - scsi_hba_fini(&modlinkage); - - mutex_destroy(&i2ohba_log_mutex); - ddi_soft_state_fini(&i2ohba_state); - - return (ret); -} - -/* - * Given the device number return the devinfo pointer - * from the scsi_device structure. - */ -/*ARGSUSED*/ -static int -i2ohba_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) -{ - return (DDI_FAILURE); -} - - -/* - * Attach an instance of an i2o hba OSM module. Allocate data structures, - * initialize the OSM and send commands to IOP to bring I2O on line. - */ -/*ARGSUSED*/ -static int -i2ohba_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) -{ - scsi_hba_tran_t *tran = NULL; - char prop_str[32]; - int i, id, tid2scsi; - int freecount = 0; - int ishdlalloc = 0; - struct i2ohba *i2ohba; - int instance; - size_t lct_size, lct_real_size, lct_rlen; - i2o_lct_t *lct_buf; - ddi_dma_handle_t lctbuf_dmahandle; - ddi_acc_handle_t lctbuf_dmaacchandle; - - instance = ddi_get_instance(dip); - - switch (cmd) { - case DDI_ATTACH: - dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; - dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; - /* currently for x86 PCI, we'll use little endian */ - dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; - break; - - /* XXXLWXXX will work on it more */ - case DDI_RESUME: - case DDI_PM_RESUME: - - default: - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_attach%d: " - "cmd != DDI_ATTACH", instance); - return (DDI_FAILURE); - } - - /* - * I2O comes in at intr level 5 - */ - if (ddi_intr_hilevel(dip, 0) != 0) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_attach%d: high-level " - "interrupt not supported", instance); - return (DDI_FAILURE); - } - - /* - * Allocate i2ohba data structure. - */ - if (ddi_soft_state_zalloc(i2ohba_state, instance) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba%d: Failed to alloc" - " soft state", instance); - return (DDI_FAILURE); - } - - i2ohba = ddi_get_soft_state(i2ohba_state, instance); - - if (i2ohba == (struct i2ohba *)NULL) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba%d: Bad soft state", - instance); - ddi_soft_state_free(i2ohba_state, instance); - return (DDI_FAILURE); - } - - /* - * save the dip info - */ - i2ohba->i2ohba_dip = dip; - - /* - * register OSM with message layer - */ - if (i2o_msg_osm_register(dip, &i2ohba->i2ohba_iophdl) - != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba%d: Registeration Fail " - "with IOP", instance); - goto cleanup; - } - - /* - * get the LCT from iop - */ - if (i2o_msg_get_lct(i2ohba->i2ohba_iophdl, NULL, NULL, - &lct_size, NULL) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba%d: Can't get LCT SIZE " - "info from IOP", instance); - goto cleanup; - } - -retry: - /* - * first get the size from IOP, then - * DMA Allocate it. - */ - if (lct_size) { - if (!ishdlalloc) { - if (ddi_dma_alloc_handle(dip, &i2ohba_dmasgl_attr, - DDI_DMA_SLEEP, NULL, &lctbuf_dmahandle) != - DDI_SUCCESS) - goto cleanup; - } - ishdlalloc = 1; -#ifdef I2OHBA_DEBUG - ddi_dma_alloc_hdl++; -#endif - if (ddi_dma_mem_alloc(lctbuf_dmahandle, (size_t) - lct_size, &dev_attr, DDI_DMA_STREAMING, - DDI_DMA_SLEEP, NULL, (caddr_t *)&lct_buf, &lct_rlen, - &lctbuf_dmaacchandle) != DDI_SUCCESS) - goto cleanup; -#ifdef I2OHBA_DEBUG - ddi_dma_alloc_mem++; -#endif - freecount = 1; - - } else { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba%d: Invalid LCT size", - instance); - goto cleanup; - } - - /* - * with the right size buffer, now get the table - */ - if (i2o_msg_get_lct(i2ohba->i2ohba_iophdl, lct_buf, lct_size, - NULL, &lct_real_size) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba%d: Getting LCT table " - "info failed", instance); - goto cleanup; - } - - /* - * partial transfer - */ - if (lct_real_size > lct_size) { - ddi_dma_mem_free(&lctbuf_dmaacchandle); -#ifdef I2OHBA_DEBUG - ddi_dma_free_mem++; -#endif - lct_size = lct_real_size; - goto retry; - } - - /* - * Set up TID->SCSI info map, query all unclaimed SCSI devices - */ - if (tid2scsi = i2ohba_i_tid_to_scsi(dip, i2ohba, lct_buf, - lct_real_size, lctbuf_dmaacchandle)) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba%d: Setup TID to SCSI " - "info map failed", instance); - goto cleanup; - } - - /* free dma, may be XXLWXX we can keep it for later LCT update */ - freecount = 0; - ddi_dma_mem_free(&lctbuf_dmaacchandle); -#ifdef I2OHBA_DEBUG - ddi_dma_free_mem++; -#endif - ishdlalloc = 0; - ddi_dma_free_handle(&lctbuf_dmahandle); -#ifdef I2OHBA_DEBUG - ddi_dma_bind_free++; -#endif - - /* - * Allocate a transport structure - */ - tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP); - - i2ohba->i2ohba_tran = tran; - i2ohba->i2ohba_dip = dip; - - tran->tran_hba_private = i2ohba; - tran->tran_tgt_private = NULL; - tran->tran_tgt_init = i2ohba_tran_tgt_init; - tran->tran_tgt_probe = (int (*)())scsi_hba_probe; - tran->tran_tgt_free = (void (*)())NULL; - - tran->tran_start = i2ohba_scsi_start; - tran->tran_abort = i2ohba_scsi_abort; - tran->tran_reset = i2ohba_scsi_reset; - tran->tran_getcap = i2ohba_scsi_getcap; - tran->tran_setcap = i2ohba_scsi_setcap; - tran->tran_init_pkt = i2ohba_scsi_init_pkt; - tran->tran_destroy_pkt = i2ohba_scsi_destroy_pkt; - tran->tran_dmafree = i2ohba_scsi_dmafree; - tran->tran_sync_pkt = i2ohba_scsi_sync_pkt; - tran->tran_reset_notify = i2ohba_scsi_reset_notify; - tran->tran_get_bus_addr = NULL; - tran->tran_get_name = NULL; - - - /* - * Attach this instance of the hba - */ - if (scsi_hba_attach_setup(dip, &i2ohba_dma_attr, tran, - 0) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?scsi_hba_attach failed"); - goto cleanup; - } - - /* - * find scsi host id property - */ - id = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "scsi-initiator-id", -1); - if (id != scsi_host_id && - (id >= 0 && id < N_I2OHBA_TARGETS_WIDE)) { - i2ohba->i2ohba_initiator_id = (uint8_t)id; - } else { - i2ohba->i2ohba_initiator_id = (uint8_t)scsi_host_id; - } - - /* - * property: look up the scsi-options property - */ - i2ohba->i2ohba_scsi_options = - ddi_getprop(DDI_DEV_T_ANY, dip, 0, "scsi-options", - I2OHBA_DEFAULT_SCSI_OPTIONS); - - /* - * property: if target<n>-scsi-options property exists, use it; - * otherwise use the i2o_scsi_options - */ - for (i = 0; i < N_I2OHBA_TARGETS_WIDE; i++) { - (void) sprintf(prop_str, "target%x-scsi-options", i); - i2ohba->i2ohba_target_scsi_option[i] = ddi_getprop( - DDI_DEV_T_ANY, dip, 0, prop_str, - i2ohba->i2ohba_scsi_options); - - if (i2ohba->i2ohba_target_scsi_option[i] != - i2ohba->i2ohba_scsi_options) { - i2ohba_i_log(NULL, CE_CONT, - "?i2ohba:target%x-scsi-options=0x%x", - i, i2ohba->i2ohba_target_scsi_option[i]); - } - } - - - i2ohba->i2ohba_scsi_reset_delay = - ddi_getprop(DDI_DEV_T_ANY, dip, 0, "scsi-reset-delay", - i2ohba_scsi_reset_delay); - - if (i2ohba->i2ohba_scsi_reset_delay != i2ohba_scsi_reset_delay) { - i2ohba_i_log(NULL, CE_CONT, - "?i2ohba_scsi-reset-delay=%d", - i2ohba->i2ohba_scsi_reset_delay); - } - - - - /* - * set up watchdog for this i2o - */ - i2ohba->i2ohba_timeout_id = timeout(i2ohba_i_watch, (caddr_t)i2ohba, - i2ohba_tick); - - /* - * initialized I2OHBA request mutex and reset mutex - */ - mutex_init(I2OHBA_REQ_MUTEX(i2ohba), NULL, MUTEX_DRIVER, NULL); - mutex_init(I2OHBA_RESET_MUTEX(i2ohba), NULL, MUTEX_DRIVER, NULL); - cv_init(I2OHBA_RESET_CV(i2ohba), NULL, CV_DRIVER, NULL); - - I2OHBA_MUTEX_ENTER(i2ohba); - /* - * Initialize the default Target Capabilites and Sync Rates - */ - (void) i2ohba_i_initcap(i2ohba); - - /* - * reset i2ohba/bus and initialize capabilities - * if (i2ohba_i_reset_interface(i2ohba, I2OHBA_FORCE_BUS_RESET)) { - * goto cleanup; - * } - */ - I2OHBA_MUTEX_EXIT(i2ohba); - - ddi_report_dev(dip); - i2ohba->i2ohba_throttle = 0; - - DEBUGF(1, (CE_CONT, "i2ohba_attach%d: Succeeded", instance)); - - return (DDI_SUCCESS); - -cleanup: - DEBUGF(1, (CE_CONT, "?i2ohba_attach%d: Unable to attach", instance)); - - if (tid2scsi) { - i2o_tid_scsi_ent_t *map = i2ohba->i2ohba_tid_scsi_map; - - /* - * if tid_to_scsi has succeeded, then at least - * we have the HBA node claimed. - */ - (void) i2ohba_utilclaim_msg(i2ohba, i2ohba->i2ohba_tid, - I2O_UTIL_CLAIM_RELEASE); - - DEBUGF(1, (CE_CONT, "?Utilunclaim %d", i2ohba->i2ohba_tid)); - - for (i = 0; i < N_I2OHBA_TARGETS_WIDE; i++) { - if (map[i].tid != 0) - (void) i2ohba_utilclaim_msg(i2ohba, - map[i].tid, - I2O_UTIL_CLAIM_RELEASE); - } - - } - - if (freecount) { - ddi_dma_mem_free(&lctbuf_dmaacchandle); - } - if (ishdlalloc) { - ddi_dma_free_handle(&lctbuf_dmahandle); - } - - if (i2ohba->i2ohba_timeout_id != 0) { - i2ohba->i2ohba_shutdown = 1; - (void) untimeout(i2ohba->i2ohba_timeout_id); - i2ohba->i2ohba_timeout_id = 0; - } - - if (tran) { - scsi_hba_tran_free(tran); - } - - if (i2ohba->i2ohba_iophdl) - i2o_msg_osm_unregister(&i2ohba->i2ohba_iophdl); - - ddi_soft_state_free(i2ohba_state, instance); - - return (DDI_FAILURE); -} - -/* - * Function name: i2ohba_i_tid_to_scsi - * - * Return Values: -1 Failed - * 0 Success - * - * Description : Take in the LCT (logical configuration table), and - * parse it through to find the appropriated SCSI target - * devices that belongs to this HBA. Then send a - * I2O_UTIL_PARAM_GET message to the target device to - * to get its parameters, ie SCSI ID and build a - * tid-to-scsi.id map. - */ -/*ARGSUSED*/ -static int -i2ohba_i_tid_to_scsi(dev_info_t *dip, struct i2ohba *i2ohba, - i2o_lct_t *lct_buf, size_t lct_real_size, - ddi_acc_handle_t lctbuf_dmaacchandle) -{ - i2o_tid_scsi_ent_t *map = i2ohba->i2ohba_tid_scsi_map; - uint_t tablesize, actualtbl; - i2o_lct_entry_t *lctentptr; - int i, count, entries = 0, rval = -1; - - /* - * translating dev_addr field in the dev_info struct to TID - */ - - i2ohba->i2ohba_tid = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "i2o-device-id", -1); - - /* - * scan the table for SCSI bus/devices - */ - tablesize = ddi_get16(lctbuf_dmaacchandle, &lct_buf->TableSize); - - if (!tablesize) { - i2ohba_i_log(NULL, CE_WARN, "?i2o_i_tid_to_scsi: Invalid " - "tablesize"); - return (rval); - } - - /* - * lct table size in WORDS - */ - actualtbl = (tablesize << 2) - sizeof (i2o_lct_t) + - sizeof (i2o_lct_entry_t); - - actualtbl = actualtbl/sizeof (i2o_lct_entry_t); - - /* scan through the table */ - for (count = 0; count < actualtbl; count++) { - uint16_t userid, parentid = 0; - - lctentptr = &(lct_buf->LCTEntry[count]); - userid = get_lct_entry_UserTID(lctentptr, lctbuf_dmaacchandle); - parentid = get_lct_entry_ParentTID(lctentptr, - lctbuf_dmaacchandle); - - /* unclaim devices */ - if (userid == 0xFFF) { - int class; - uint16_t tid; - - class = get_lct_entry_Class(lctentptr, - lctbuf_dmaacchandle); - tid = get_lct_entry_LocalTID(lctentptr, - lctbuf_dmaacchandle); - - /* - * search for SCSI Peripheral with Parent ID - * as the same as hba's TID and unclaimed devices - */ - - if ((parentid == i2ohba->i2ohba_tid) && - (class == I2O_CLASS_SCSI_PERIPHERAL)) { - /* claim it */ - if (i2ohba_utilclaim_msg(i2ohba, tid, - I2O_UTIL_CLAIM)) { - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_i_tid_to_scsi: " - "i2ohba_utilclaim_msg failed"); - } else { - i2ohba_i_log(NULL, CE_CONT, - "?utilclaim:" - "Tid: 0x%x, SCSI_PERIPHERAL", tid); - /* claim succeed */ - map[entries].tid = tid; - entries++; - } - } - - /* - * find our own bus adapter port and - * claim it as well - */ - if ((tid == i2ohba->i2ohba_tid) && - (class == I2O_CLASS_BUS_ADAPTER_PORT)) { - if (i2ohba_utilclaim_msg(i2ohba, tid, - I2O_UTIL_CLAIM)) { - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_i_tid_to_scsi: " - "i2ohba_utilclaim_msg failed"); - /* - * it is pointless to continue here - * because if we can't claim the bus port - * then we can't do anything except for - * sending utilgetparm and busreset msgs - */ - break; - } else { - i2ohba_i_log(NULL, CE_CONT, - "?utilclaim:" - "Tid: 0x%x, BUS_ADAPTER_PORT", tid); - rval = 0; - } - } - - } /* userid == 0xFFF */ - } /* for loop */ - - /* - * initialized all utilparam message's mutex's - */ - for (i = 0; i < N_I2OHBA_TARGETS_WIDE; i++) { - mutex_init(I2OHBA_UTILPARAM_MUTEX(i2ohba, i), NULL, - MUTEX_DRIVER, NULL); - cv_init(I2OHBA_UTILPARAM_CV(i2ohba, i), NULL, - CV_DRIVER, NULL); - } - - /* - * Now allocated parameter for each qualified peripheral - */ - for (i = 0; i < entries; i++) { - /* - * call i2ohba_utilparamget_msg to get - * parameters - */ - rval = i2ohba_utilparamget_msg(i2ohba, i, ALL_UTILPARAMS); - if (rval) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_i_tid_to_scsi:" - " i2ohba_utilparamget_msg failed"); - } - - } /* for loop */ - - if (i > 0) - rval = 0; - return (rval); - -} - -/* - * Function name: i2ohba_utilcliam_msg() - * - * Return Values: 0 - success - * -1 - fail to claim the device - * - * Description : send a utilclaim or utilclaim_release msg - * to the device - * - * This function is called from i2ohba_i_tid_to_scsi() - */ -static int -i2ohba_utilclaim_msg(struct i2ohba *i2ohba, uint16_t tid, int action) -{ - int rval = -1; - i2o_util_claim_message_t *msgptr; - i2o_msg_handle_t msg_handle; - ddi_acc_handle_t acc_handle; - struct i2ohba_util *sp; - - if (i2o_msg_alloc(i2ohba->i2ohba_iophdl, I2O_MSG_SLEEP, NULL, - (void *)&msgptr, &msg_handle, &acc_handle) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_utilclaim_msg: " - "i2o_msg_alloc failed"); - return (rval); - } - - /* - * construct a i2o_hba_bus_reset_message - */ - msgptr->StdMessageFrame.VersionOffset = 0x01; - msgptr->StdMessageFrame.MsgFlags = 0; - ddi_put16(acc_handle, &msgptr->StdMessageFrame.MessageSize, - sizeof (i2o_util_claim_message_t) >> 2); - put_msg_TargetAddress(&msgptr->StdMessageFrame, tid, acc_handle); - put_msg_InitiatorAddress(&msgptr->StdMessageFrame, I2O_OSM_TID, - acc_handle); - put_msg_Function(&msgptr->StdMessageFrame, action, acc_handle); - ddi_put32(acc_handle, - (uint32_t *)&msgptr->StdMessageFrame.InitiatorContext, - (uint32_t)i2ohba_utilmsg_comp); - ddi_put8(acc_handle, &msgptr->ClaimType, I2O_CLAIM_TYPE_PRIMARY_USER); - - /* - * allocating synchronized status buffer - */ - sp = kmem_alloc(sizeof (struct i2ohba_util), KM_SLEEP); - - ddi_put32(acc_handle, &msgptr->TransactionContext, - (uint32_t)(uintptr_t)sp); - - /* - * initialized a mutex and cond variable to - * send message to IOP, and wait for it to signal back - */ - sp->mutex = I2OHBA_UTILPARAM_MUTEX(i2ohba, 0); - sp->cv = I2OHBA_UTILPARAM_CV(i2ohba, 0); - mutex_enter(sp->mutex); - sp->wakeup = UTIL_MSG_SLEEP; - sp->status = 0; - (void) i2o_msg_send(i2ohba->i2ohba_iophdl, msgptr, msg_handle); - while (!sp->wakeup) - cv_wait(sp->cv, sp->mutex); - mutex_exit(sp->mutex); - - /* - * process reply message - */ - - switch (sp->status) { - case I2O_REPLY_STATUS_SUCCESS: - rval = 0; - DEBUGF(1, (CE_CONT, "Reset Succeeded")); - break; - default: - i2ohba_i_log(NULL, CE_CONT, "Reset Failed"); - /* - * Failed the reset for now, - * we can also parse the AdapterStatus - * and retry if needed - */ - break; - } - -cleanup: - if (sp) - kmem_free(sp, sizeof (struct i2ohba_util)); - return (rval); -} - -/* - * i2ohba_utilmsg_comp - * passed the status back to the caller to decided - * what to do with the error code. - */ -/*ARGSUSED*/ -static void -i2ohba_utilmsg_comp(i2o_message_frame_t *msg, ddi_acc_handle_t acc_handle) -{ - - i2o_single_reply_message_frame_t *reply; - int type, reqstatus, detailstatus, adptrstatus; - struct i2ohba_util *sp; - - - reply = (i2o_single_reply_message_frame_t *)msg; - sp = (struct i2ohba_util *)(uintptr_t)ddi_get32(acc_handle, - &reply->TransactionContext); - - type = get_msg_Function(&reply->StdMessageFrame, acc_handle); - - switch (type) { - /* - * Bus Reset - */ - case I2O_HBA_BUS_RESET: - detailstatus = ddi_get16(acc_handle, - &reply->DetailedStatusCode); - adptrstatus = detailstatus & I2O_SCSI_HBA_DSC_MASK; - if (adptrstatus != I2O_HBA_DSC_BUS_RESET) - reqstatus = I2O_REPLY_STATUS_TRANSACTION_ERROR; - else - reqstatus = reply->ReqStatus; - break; - - /* - * Utility Class Function - */ - case I2O_UTIL_PARAMS_GET: - case I2O_UTIL_PARAMS_SET: - case I2O_UTIL_CLAIM: - case I2O_UTIL_CLAIM_RELEASE: - /* - * Adapter Class Function - */ - case I2O_HBA_ADAPTER_RESET: - case I2O_SCSI_DEVICE_RESET: - reqstatus = reply->ReqStatus; - break; - - default: - DEBUGF(2, (CE_CONT, "Error! Not Supported")); - return; - - } - - mutex_enter(sp->mutex); - sp->wakeup = UTIL_MSG_WAKEUP; - sp->status = reqstatus; - cv_broadcast(sp->cv); - mutex_exit(sp->mutex); -} - -/*ARGSUSED*/ -static int -i2ohba_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) -{ - - struct i2ohba *i2ohba; - scsi_hba_tran_t *tran; - int instance = ddi_get_instance(dip); - int i; - - switch (cmd) { - case DDI_DETACH: - { - if ((tran = ddi_get_driver_private(dip)) == NULL) - return (DDI_FAILURE); - - i2ohba = TRAN2I2OHBA(tran); - if (!i2ohba) { - return (DDI_FAILURE); - } - - if (i2ohba->i2ohba_iophdl) - i2o_msg_osm_unregister(&i2ohba->i2ohba_iophdl); - - /* - * deallocate reset notify callback list - */ - scsi_hba_reset_notify_tear_down( - i2ohba->i2ohba_reset_notify_listf); - - if (i2ohba->i2ohba_timeout_id != 0) { - (void) untimeout(i2ohba->i2ohba_timeout_id); - i2ohba->i2ohba_timeout_id = NULL; - } - - /* - * remove device MT locks - */ - mutex_destroy(I2OHBA_REQ_MUTEX(i2ohba)); - mutex_destroy(I2OHBA_RESET_MUTEX(i2ohba)); - cv_destroy(I2OHBA_RESET_CV(i2ohba)); - - for (i = 0; i < N_I2OHBA_TARGETS_WIDE; i++) { - - mutex_destroy(I2OHBA_UTILPARAM_MUTEX(i2ohba, i)); - cv_destroy(I2OHBA_UTILPARAM_CV(i2ohba, i)); - } - - /* - * remove properties created druing attach() - */ - ddi_prop_remove_all(dip); - - /* - * Delete the DMA limits, transport vectors and remove the - * device links to the scsi_transport layer. - * -- ddi_set_driver_private(dip, NULL) - */ - (void) scsi_hba_detach(dip); - - /* - * Free the scsi_transport structure for this device. - */ - scsi_hba_tran_free(tran); - - i2ohba->i2ohba_dip = (dev_info_t *)NULL; - i2ohba->i2ohba_tran = (scsi_hba_tran_t *)NULL; - - ddi_soft_state_free(i2ohba_state, instance); - ddi_remove_minor_node(dip, NULL); - - return (DDI_SUCCESS); - } - /* XXXLWXXX */ - case DDI_SUSPEND: - case DDI_PM_SUSPEND: - default: - return (DDI_FAILURE); - } -} - - -/* - * Function name : i2ohba_tran_tgt_init - * - * Return Values : DDI_SUCCESS if target supported, DDI_FAILURE otherwise - * - */ -/*ARGSUSED*/ -static int -i2ohba_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, - scsi_hba_tran_t *tran, struct scsi_device *sd) -{ - return ((sd->sd_address.a_target < N_I2OHBA_TARGETS_WIDE && - sd->sd_address.a_lun == 0) ? DDI_SUCCESS : - DDI_FAILURE); -} - - -/* - * Function name : i2ohba_i_initcap - * - * Return Values : NONE - * Description : Initializes the default target capabilites and - * Sync Rates. - * - * Context : Called from the user thread through attach. - * - */ -static void -i2ohba_i_initcap(struct i2ohba *i2ohba) -{ - int i, option; - uint16_t cap, synch; - uint8_t offset; - i2o_tid_scsi_ent_t **map = i2ohba->i2ohba_tgt_id_map; - - for (i = 0; i < N_I2OHBA_TARGETS_WIDE; i++) { - cap = 0; - synch = 0; - option = 0; - offset = 0; - - if (map[i] == NULL) - continue; - - /* - * Check for connect/disconnect - */ - if (map[i]->scsi_info_scalar.Flags & - I2O_SCSI_ENABLE_DISCONNECT) { - option |= SCSI_OPTIONS_DR; - cap |= I2OHBA_CAP_DISCONNECT; - } else { - option &= ~SCSI_OPTIONS_DR; - } - - /* - * Check for Wide data - */ - if (map[i]->scsi_info_scalar.Flags & - I2O_SCSI_DATA_WIDTH_MASK) { - option |= SCSI_OPTIONS_WIDE; - cap |= I2OHBA_CAP_WIDE; - } else { - option &= ~SCSI_OPTIONS_WIDE; - } - - /* - * Check for synchronization - */ - if (map[i]->scsi_info_scalar.Flags & - I2O_SCSI_ENABLE_SYNC_NEGOTIATION) { - option |= SCSI_OPTIONS_SYNC; - cap |= I2OHBA_CAP_SYNC; - } else { - option &= ~SCSI_OPTIONS_SYNC; - } - - synch = (uint16_t)map[i]->scsi_info_scalar.NegSyncRate; - offset = (uint8_t)map[i]->scsi_info_scalar.NegOffset; - - /* - * Check for tag queuing capability - */ - if (map[i]->scsi_info_scalar.QueueDepth) { - option |= SCSI_OPTIONS_TAG; - cap |= I2OHBA_CAP_TAG; - } else { - option &= ~SCSI_OPTIONS_TAG; - } - - i2ohba->i2ohba_target_scsi_option[i] = option; - i2ohba->i2ohba_cap[i] = cap; - i2ohba->i2ohba_synch[i] = synch; - i2ohba->i2ohba_offset[i] = offset; - } -} - - - -/* - * Function name : i2ohba_scsi_getcap() - * - * Return Values : current value of capability, if defined - * -1 if capability is not defined - * - * Description : returns current capability value - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -static int -i2ohba_scsi_getcap(struct scsi_address *ap, char *cap, int whom) -{ - struct i2ohba *i2ohba = ADDR2I2OHBA(ap); - i2o_tid_scsi_ent_t **map = i2ohba->i2ohba_tgt_id_map; - uint8_t tgt = ap->a_target; - int rval = 0; - - /* - * We don't allow inquiring about capabilities for other targets - */ - if (cap == NULL || whom == 0 || map[tgt] == NULL) { - return (-1); - } - - I2OHBA_MUTEX_ENTER(i2ohba); - - switch (scsi_hba_lookup_capstr(cap)) { - case SCSI_CAP_GEOMETRY: - { /* left this code from adp driver */ - uint32_t total_sectors, c, h, s, t; - c = 1024L; - s = 62L; - - total_sectors = i2ohba->i2ohba_totsec[tgt]; - - t = c * s; - h = total_sectors / t; - if (total_sectors % t) { - h ++; - t = c * h; - s = total_sectors / t; - if (total_sectors % t) { - s++; - t = h * s; - c = total_sectors / t; - } - } - if (c == 0) rval = 1; - - rval = ((h << 16) | s); - break; - } - case SCSI_CAP_DMA_MAX: - rval = 1 << 24; /* Limit to 16MB max transfer */ - break; - case SCSI_CAP_MSG_OUT: - rval = 1; - break; - case SCSI_CAP_DISCONNECT: - if ((i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_DR) == 0) { - break; - } else if ((i2ohba->i2ohba_cap[tgt] & I2OHBA_CAP_DISCONNECT) - == 0) { - break; - } - rval = 1; - break; - case SCSI_CAP_SYNCHRONOUS: - if ((i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_SYNC) == 0) { - break; - } else if ((i2ohba->i2ohba_cap[tgt] & I2OHBA_CAP_SYNC) == 0) { - break; - } - rval = 1; - break; - case SCSI_CAP_WIDE_XFER: - if ((i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_WIDE) == 0) { - break; - } else if ((i2ohba->i2ohba_cap[tgt] & I2OHBA_CAP_WIDE) == 0) { - break; - } - rval = 1; - break; - case SCSI_CAP_TAGGED_QING: - if ((i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_DR) == 0 || - (i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_TAG) == 0) { - break; - } else if ((i2ohba->i2ohba_cap[tgt] & I2OHBA_CAP_TAG) == 0) { - break; - } - rval = 1; - break; - case SCSI_CAP_UNTAGGED_QING: - rval = 0; - break; - case SCSI_CAP_PARITY: - if (i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_PARITY) { - rval = 1; - } - break; - case SCSI_CAP_INITIATOR_ID: - rval = i2ohba->i2ohba_initiator_id; - break; - case SCSI_CAP_ARQ: - rval = 1; - break; - case SCSI_CAP_LINKED_CMDS: - break; - case SCSI_CAP_RESET_NOTIFICATION: - rval = 1; - break; - default: - rval = -1; - break; - } - - I2OHBA_MUTEX_EXIT(i2ohba); - - return (rval); -} - - -/* - * Function name : i2ohba_scsi_setcap() - * - * Return Values : 1 - capability exists and can be set to new value - * 0 - capability could not be set to new value - * -1 - no such capability - * - * Description : sets a capability for a target - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -static int -i2ohba_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom) -{ - struct i2ohba *i2ohba = ADDR2I2OHBA(ap); - i2o_tid_scsi_ent_t **map = i2ohba->i2ohba_tgt_id_map; - uint8_t tgt = ap->a_target; - int update = 0; - int sync = 0; - int rval = 0; - - /* - * We don't allow setting capabilities for other targets - * and the targets that are not in this OSM's control - */ - if (cap == NULL || whom == 0 || map[tgt] == NULL) { - return (-1); - } - - I2OHBA_MUTEX_ENTER(i2ohba); - - switch (scsi_hba_lookup_capstr(cap)) { - case SCSI_CAP_DMA_MAX: - case SCSI_CAP_MSG_OUT: - case SCSI_CAP_PARITY: - case SCSI_CAP_UNTAGGED_QING: - case SCSI_CAP_LINKED_CMDS: - case SCSI_CAP_RESET_NOTIFICATION: - case SCSI_CAP_GEOMETRY: - /* - * None of these are settable via - * the capability interface. - */ - break; - - case SCSI_CAP_SECTOR_SIZE: - if (value) { - i2ohba->i2ohba_secsz[tgt] = value; - rval = 1; - } - break; - - case SCSI_CAP_TOTAL_SECTORS: - if (value) { - i2ohba->i2ohba_totsec[tgt] = value; - rval = 1; - } - break; - case SCSI_CAP_ARQ: - if (value) { - i2ohba->i2ohba_cap[tgt] |= I2OHBA_CAP_AUTOSENSE; - } else { - i2ohba->i2ohba_cap[tgt] &= ~I2OHBA_CAP_AUTOSENSE; - } - rval = 1; - break; - - /* disconnect/reconncet either the target supports or doesn't */ - case SCSI_CAP_DISCONNECT: - if ((i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_DR) == 0) { - break; - } else { - if (value) { - if ((i2ohba->i2ohba_cap[tgt] & - I2OHBA_CAP_DISCONNECT) == 0) { - if (i2ohba_utilparamset_msg(i2ohba, - tgt, map[tgt]->tid, - I2O_SCSI_DEVICE_INFO_GROUP_NO, 0x1, - I2O_SCSI_ENABLE_DISCONNECT) != 0) - break; - i2ohba->i2ohba_cap[tgt] |= - I2OHBA_CAP_DISCONNECT; - } - } else { - if ((i2ohba->i2ohba_cap[tgt] & - I2OHBA_CAP_DISCONNECT) == 1) { - if (i2ohba_utilparamset_msg(i2ohba, - tgt, map[tgt]->tid, - I2O_SCSI_DEVICE_INFO_GROUP_NO, 0x1, - I2O_SCSI_DISABLE_DISCONNECT) != 0) - break; - i2ohba->i2ohba_cap[tgt] &= - ~I2OHBA_CAP_DISCONNECT; - } - } - } - rval = 1; - break; - - /* these can be set through UtilParamSet message */ - case SCSI_CAP_SYNCHRONOUS: - if ((i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_SYNC) == 0) { - break; - } else { - if (value) { - if ((i2ohba->i2ohba_cap[tgt] & - I2OHBA_CAP_SYNC) == 0) { - if (i2ohba_utilparamset_msg(i2ohba, - tgt, map[tgt]->tid, - I2O_SCSI_DEVICE_INFO_GROUP_NO, 0x1, - I2O_SCSI_ENABLE_SYNC_NEGOTIATION) - != 0) - break; - /* set sync speed to Max */ - if (i2ohba_utilparamset_msg(i2ohba, - tgt, map[tgt]->tid, - I2O_SCSI_DEVICE_INFO_GROUP_NO, 0xA, - 0xFFFF) != 0) - break; - /* read the set value */ - if (i2ohba_utilparamget_msg(i2ohba, - tgt, SYNC_UTILPARAM) != 0) - break; - i2ohba->i2ohba_cap[tgt] |= - I2OHBA_CAP_SYNC; - sync++; - update++; - } - } else { - if ((i2ohba->i2ohba_cap[tgt] & - I2OHBA_CAP_SYNC) == 1) { - if (i2ohba_utilparamset_msg(i2ohba, - tgt, map[tgt]->tid, - I2O_SCSI_DEVICE_INFO_GROUP_NO, 0x1, - I2O_SCSI_DISABLE_SYNC_NEGOTIATION) - != 0) - break; - i2ohba->i2ohba_cap[tgt] &= - ~I2OHBA_CAP_SYNC; - update++; - } - } - } - rval = 1; - break; - case SCSI_CAP_TAGGED_QING: - if ((i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_DR) == 0 || - (i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_TAG) == 0) { - break; - } else { - if (value) { - if ((i2ohba->i2ohba_cap[tgt] & - I2OHBA_CAP_TAG) == 0) { - if (i2ohba_utilparamset_msg(i2ohba, - tgt, map[tgt]->tid, - I2O_SCSI_DEVICE_INFO_GROUP_NO, 0x5, - 0) != 0) - break; - i2ohba->i2ohba_cap[tgt] |= - I2OHBA_CAP_TAG; - update++; - } - } else { - if ((i2ohba->i2ohba_cap[tgt] & - I2OHBA_CAP_TAG) == 1) { - if (i2ohba_utilparamset_msg(i2ohba, - tgt, map[tgt]->tid, - I2O_SCSI_DEVICE_INFO_GROUP_NO, 0x5, - (uint16_t)1) != 0) - break; - i2ohba->i2ohba_cap[tgt] &= - ~I2OHBA_CAP_TAG; - update++; - } - } - } - rval = 1; - break; - case SCSI_CAP_WIDE_XFER: - if ((i2ohba->i2ohba_target_scsi_option[tgt] & - SCSI_OPTIONS_WIDE) == 0) { - break; - } else { - if (value) { - if ((i2ohba->i2ohba_cap[tgt] & - I2OHBA_CAP_WIDE) == 0) { - if (i2ohba_utilparamset_msg(i2ohba, - tgt, map[tgt]->tid, - I2O_SCSI_DEVICE_INFO_GROUP_NO, 0x1, - I2O_SCSI_DATA_WIDTH_16) != 0) - break; - i2ohba->i2ohba_cap[tgt] |= - I2OHBA_CAP_WIDE; - update++; - } - } else { - if ((i2ohba->i2ohba_cap[tgt] & - I2OHBA_CAP_WIDE) == 1) { - if (i2ohba_utilparamset_msg(i2ohba, - tgt, map[tgt]->tid, - I2O_SCSI_DEVICE_INFO_GROUP_NO, 0x1, - I2O_SCSI_DATA_WIDTH_8) != 0) - break; - i2ohba->i2ohba_cap[tgt] &= - ~I2OHBA_CAP_WIDE; - update++; - } - } - } - rval = 1; - break; - case SCSI_CAP_INITIATOR_ID: - if (value < N_I2OHBA_TARGETS_WIDE) { - if (i2ohba->i2ohba_initiator_id != (uint16_t)value) { - /* - * set Initiator SCSI ID - */ - if (i2ohba_utilparamset_msg(i2ohba, - i2ohba->i2ohba_initiator_id, - i2ohba->i2ohba_tid, - I2O_HBA_SCSI_CONTROLLER_INFO_GROUP_NO, 0x4, - value) == 0) { - rval = 1; - i2ohba->i2ohba_initiator_id = value; - } - } - } - break; - - default: - rval = -1; - break; - } - - - /* - * now set flag so latter in i2ohba_i_watch(), - * we can set prop_update - */ - if ((rval == 1) && (update > 0)) { - i2ohba->i2ohba_need_prop_update |= 1 << tgt; - if (sync) - i2ohba_i_updatesync(i2ohba, tgt); - } - - I2OHBA_MUTEX_EXIT(i2ohba); - - return (rval); -} - -/* - * Function name : i2ohba_i_updatesync() - * - * Return Values : -1 failed - * 0 success - * - * Description : modifies/update target sync mode speed, widexfer, - * and TQ. - * - * Context : Can be called from different kernel process threads. - * Can not be called by interrupt thread - */ -static void -i2ohba_i_updatesync(struct i2ohba *i2ohba, int tgt) -{ - uint16_t synch; - uint8_t offset; - i2o_tid_scsi_ent_t **map = i2ohba->i2ohba_tgt_id_map; - - if (map[tgt] == NULL) - return; - - if (map[tgt]->scsi_info_scalar.Flags & - I2O_SCSI_ENABLE_SYNC_NEGOTIATION) { - synch = (uint16_t)map[tgt]->scsi_info_scalar.NegSyncRate; - offset = (uint8_t)map[tgt]->scsi_info_scalar.NegOffset; - - i2ohba->i2ohba_synch[tgt] = synch; - i2ohba->i2ohba_offset[tgt] = offset; - } -} - -/* - * Function name : i2ohba_i_update_props() - * - * Description : Creates/modifies/removes a target sync mode speed, - * wide, and TQ properties - * If offset is 0 then asynchronous mode is assumed and the - * property is removed, if it existed. - * - * Context : Can be called from different kernel process threads. - * Can not be called by interrupt thread - */ -static void -i2ohba_i_update_props(struct i2ohba *i2ohba, int tgt) -{ - static char property[32]; - int xfer_speed = 0; - int wide_enabled; - int tq_enabled; - uint16_t cap; - uint16_t synch; - uint8_t offset; - - cap = i2ohba->i2ohba_cap[tgt]; - synch = i2ohba->i2ohba_synch[tgt]; - offset = i2ohba->i2ohba_offset[tgt]; - - tq_enabled = cap & I2OHBA_CAP_TAG; - wide_enabled = cap & I2OHBA_CAP_WIDE; - - if (offset && synch) { - if (wide_enabled) { - /* double xfer speed if wide has been enabled */ - xfer_speed = ((int)synch * 2); - } else { - xfer_speed = (int)(synch); - } - } - - (void) sprintf(property, "target%x-sync-speed", tgt); - i2ohba_i_update_this_prop(i2ohba, property, xfer_speed); - - (void) sprintf(property, "target%x-wide", tgt); - i2ohba_i_update_this_prop(i2ohba, property, wide_enabled); - - (void) sprintf(property, "target%x-TQ", tgt); - i2ohba_i_update_this_prop(i2ohba, property, tq_enabled); -} - -/* - * Update a property's value - */ -static void -i2ohba_i_update_this_prop(struct i2ohba *i2ohba, char *property, int value) -{ - dev_info_t *dip = i2ohba->i2ohba_dip; - - - if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, - property, value) != DDI_PROP_SUCCESS) { - i2ohba_i_log(NULL, CE_CONT, "?i2ohba_i_update_this_prop:" - " can't update %s property to 0x%x", - property, value); - } -} - - -/* - * Function name : i2ohba_scsi_init_pkt - * - * Return Values : pointer to scsi_pkt, or NULL - * Description : Called by kernel on behalf of a target driver - * calling scsi_init_pkt(9F). - * Refer to tran_init_pkt(9E) man page - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -static struct scsi_pkt * -i2ohba_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, - struct buf *bp, int cmdlen, int statuslen, int tgtlen, - int flags, int (*callback)(), caddr_t arg) -{ - struct i2ohba_cmd *sp; - struct i2ohba *i2ohba = ADDR2I2OHBA(ap); - struct scsi_pkt *new_pkt; - - ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC); - - /* - * First step of i2ohba_scsi_init_pkt: pkt allocation - */ - if (pkt == NULL) { - pkt = scsi_hba_pkt_alloc(i2ohba->i2ohba_dip, ap, cmdlen, - statuslen, tgtlen, sizeof (struct i2ohba_cmd), callback, - arg); - - if (pkt == NULL) { - return (NULL); - } - - sp = PKT2CMD(pkt); - - /* - * Initialize the new pkt - we redundantly initialize - * all the fields for illustrative purposes. - */ - sp->cmd_pkt = pkt; - sp->cmd_flags = 0; - sp->cmd_scblen = statuslen; - sp->cmd_cdblen = (uint8_t)cmdlen; - sp->cmd_privlen = tgtlen; - sp->cmd_dmahandle = NULL; - sp->cmd_dmacount = 0; - sp->cmd_cookie = 0; - pkt->pkt_address = *ap; - pkt->pkt_comp = (void (*)())NULL; - pkt->pkt_flags = 0; - pkt->pkt_time = 0; - pkt->pkt_resid = 0; - pkt->pkt_statistics = 0; - pkt->pkt_reason = 0; - - new_pkt = pkt; - } else { - sp = PKT2CMD(pkt); - new_pkt = NULL; - } - - /* - * Second step of i2ohba_scsi_init_pkt: dma allocation/move - */ - if (bp && bp->b_bcount != 0) { - if (sp->cmd_dmahandle == NULL) { - ASSERT((sp->cmd_flags & CFLAG_DMAVALID) == 0); - if (i2ohba_i_dma_alloc(i2ohba, pkt, bp, - flags, callback) == -1) { - if (new_pkt) { - scsi_hba_pkt_free(ap, new_pkt); - } - return ((struct scsi_pkt *)NULL); - } - } else { - ASSERT(new_pkt == NULL); - ASSERT(sp->cmd_flags & CFLAG_DMAVALID); - if (i2ohba_i_dma_move(i2ohba, pkt, bp) < 0) { - return ((struct scsi_pkt *)NULL); - } - } - ASSERT(sp->cmd_flags & CFLAG_DMAVALID); - DEBUGF(3, (CE_CONT, "init: bcount = %lx, resid = %lx", - bp->b_bcount, pkt->pkt_resid)); - } - - return (pkt); -} - -/* - * Function name : i2ohba_i_dma_alloc - * - * Return Values : 0 if successful, -1 if failure - * Description : allocate DMA resources - * - * Context : Can only be called from i2ohba_scsi_init_pkt() - */ -static int -i2ohba_i_dma_alloc(struct i2ohba *i2ohba, struct scsi_pkt *pkt, - struct buf *bp, int flags, int (*callback)()) -{ - struct i2ohba_cmd *sp = PKT2CMD(pkt); - int dma_flags; - int (*cb)(caddr_t); - int i; - - ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC); - - if (bp->b_flags & B_READ) { - sp->cmd_flags &= ~CFLAG_DMASEND; - dma_flags = DDI_DMA_READ; - } else { - sp->cmd_flags |= CFLAG_DMASEND; - dma_flags = DDI_DMA_WRITE; - } - - if (flags & PKT_CONSISTENT) { - sp->cmd_flags |= CFLAG_CMDIOPB; - dma_flags |= DDI_DMA_CONSISTENT; - } - - if (flags & PKT_DMA_PARTIAL) { - dma_flags |= DDI_DMA_PARTIAL; - } - - dma_flags |= DDI_DMA_REDZONE; - - cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP; - - if ((i = ddi_dma_alloc_handle(i2ohba->i2ohba_dip, - &i2ohba_dma_attr, cb, NULL, &sp->cmd_dmahandle)) - != DDI_SUCCESS) { - switch (i) { - case DDI_DMA_BADATTR: - bioerror(bp, EFAULT); - return (-1); - - case DDI_DMA_NORESOURCES: - bioerror(bp, 0); - return (-1); - - default: - i2ohba_i_log(NULL, CE_WARN, - "?ddi_dma_alloc_handle:" - " 0x%x impossible", i); - /*NOTREACHED*/ - } - } - -#ifdef I2OHBA_DEBUG - ddi_dma_bufalloc++; -#endif - - i = ddi_dma_buf_bind_handle(sp->cmd_dmahandle, bp, dma_flags, - cb, NULL, &sp->cmd_dmacookies[0], &sp->cmd_ncookies); -#ifdef I2OHBA_DEBUG - ddi_dma_buf_bind++; -#endif - - DEBUGF(3, (CE_CONT, "dma_alloc: cmd_ncookies is %d\n", - sp->cmd_ncookies)); - - switch (i) { - case DDI_DMA_PARTIAL_MAP: - ASSERT(dma_flags & DDI_DMA_PARTIAL); - - if (ddi_dma_numwin(sp->cmd_dmahandle, &sp->cmd_nwin) == - DDI_FAILURE) { - i2ohba_i_log(NULL, CE_WARN, - "?ddi_dma_numwin() failed"); - /*NOTREACHED*/ - } - - if (ddi_dma_getwin(sp->cmd_dmahandle, sp->cmd_curwin, - &sp->cmd_dma_offset, &sp->cmd_dma_len, - &sp->cmd_dmacookies[0], &sp->cmd_ncookies) == - DDI_FAILURE) { - i2ohba_i_log(NULL, CE_WARN, - "?ddi_dma_getwin() failed"); - /*NOTREACHED*/ - } - goto get_dma_cookies; - - case DDI_DMA_MAPPED: - sp->cmd_nwin = 1; - sp->cmd_dma_len = 0; - sp->cmd_dma_offset = 0; - -get_dma_cookies: - i = 0; - sp->cmd_dmacount = 0; - for (;;) { - sp->cmd_dmacount += sp->cmd_dmacookies[i++].dmac_size; - - if (i == I2OHBA_CMD_NSEGS || i == sp->cmd_ncookies) - break; - ddi_dma_nextcookie(sp->cmd_dmahandle, - &sp->cmd_dmacookies[i]); - } - - sp->cmd_cookie = i; - sp->cmd_cookiecnt = i; - - sp->cmd_flags |= CFLAG_DMAVALID; - pkt->pkt_resid = bp->b_bcount - sp->cmd_dmacount; - - DEBUGF(3, (CE_CONT, "bcount is %lx, dmacount is %lx," - " resid is %lx\n", - bp->b_bcount, sp->cmd_dmacount, pkt->pkt_resid)); - - return (0); - - case DDI_DMA_NORESOURCES: - bioerror(bp, 0); - break; - - case DDI_DMA_NOMAPPING: - bioerror(bp, EFAULT); - break; - - case DDI_DMA_TOOBIG: - bioerror(bp, EINVAL); - break; - - case DDI_DMA_INUSE: - i2ohba_i_log(NULL, CE_WARN, "?ddi_dma_buf_bind_handle:" - " DDI_DMA_INUSE impossible"); - /*NOTREACHED*/ - - default: - i2ohba_i_log(NULL, CE_WARN, "?ddi_dma_buf_bind_handle:" - " 0x%x impossible", i); - /*NOTREACHED*/ - } - - ddi_dma_free_handle(&sp->cmd_dmahandle); - sp->cmd_dmahandle = NULL; - sp->cmd_flags &= ~CFLAG_DMAVALID; - return (-1); -} - - -/* - * Function name : i2ohba_i_dma_move - * - * Return Values : 0 if successful, -1 if failure - * Description : move DMA resources to next DMA window - * - * Context : Can only be called from i2ohba_scsi_init_pkt() - */ -/*ARGSUSED*/ -static int -i2ohba_i_dma_move(struct i2ohba *i2ohba, struct scsi_pkt *pkt, struct buf *bp) -{ - struct i2ohba_cmd *sp = PKT2CMD(pkt); - int i; - - ASSERT(sp->cmd_flags & CFLAG_COMPLETED); - sp->cmd_flags &= ~CFLAG_COMPLETED; - - /* - * If there are no more cookies remaining in this window, - * must move to the next window first. - */ - if (sp->cmd_cookie == sp->cmd_ncookies) { - /* - * 1217340: cmdk reuses pkts incorrectly - */ - if (sp->cmd_curwin == sp->cmd_nwin && sp->cmd_nwin == 1) - return (0); - - /* - * At last window, cannot move - */ - if (++sp->cmd_curwin >= sp->cmd_nwin) - return (-1); - - if (ddi_dma_getwin(sp->cmd_dmahandle, sp->cmd_curwin, - &sp->cmd_dma_offset, &sp->cmd_dma_len, - &sp->cmd_dmacookies[0], &sp->cmd_ncookies) == DDI_FAILURE) - return (-1); - - sp->cmd_cookie = 0; - } else { - /* - * Still more cookies in this window - get the next one - */ - ddi_dma_nextcookie(sp->cmd_dmahandle, &sp->cmd_dmacookies[0]); - } - - /* - * Get remaining cookies in this window, up to our maximum - */ - i = 0; - for (;;) { - sp->cmd_dmacount += sp->cmd_dmacookies[i++].dmac_size; - sp->cmd_cookie++; - if (i == I2OHBA_CMD_NSEGS || sp->cmd_cookie == sp->cmd_ncookies) - break; - ddi_dma_nextcookie(sp->cmd_dmahandle, &sp->cmd_dmacookies[i]); - } - sp->cmd_cookiecnt = i; - - pkt->pkt_resid = bp->b_bcount - sp->cmd_dmacount; - return (0); -} - - -/* - * Function name : i2ohba_scsi_destroy_pkt - * - * Return Values : none - * Description : Called by kernel on behalf of a target driver - * calling scsi_destroy_pkt(9F). - * Refer to tran_destroy_pkt(9E) man page - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -static void -i2ohba_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) -{ - struct i2ohba_cmd *sp = PKT2CMD(pkt); - struct i2ohba *i2ohba = ADDR2I2OHBA(ap); - i2o_tid_scsi_ent_t **map = i2ohba->i2ohba_tgt_id_map; - uint8_t tgt = ap->a_target; - - if (map[tgt] != NULL) { - - /* - * i2o_scsi_dmafree inline to make things faster - */ - if (sp->cmd_flags & CFLAG_DMAVALID) { - /* - * Free the mapping - */ - sp->cmd_flags &= ~CFLAG_DMAVALID; - if (ddi_dma_unbind_handle(sp->cmd_dmahandle) - != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_scsi_destroy_pkt: " - "ddi_dma_unbind_handle() for dataseg" - " failed"); - /*NOTREACHED*/ - } -#ifdef I2OHBA_DEBUG - ddi_dma_buf_unbind++; -#endif - ddi_dma_free_handle(&sp->cmd_dmahandle); -#ifdef I2OHBA_DEBUG - ddi_dma_buf_free_hdl++; -#endif - sp->cmd_dmahandle = NULL; - } - } - - /* - * Free the pkt - */ - scsi_hba_pkt_free(ap, pkt); -} - - -/* - * Function name : i2ohba_scsi_dmafree() - * - * Return Values : none - * Description : free dvma resources - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -/*ARGSUSED*/ -static void -i2ohba_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) -{ - struct i2ohba_cmd *sp = PKT2CMD(pkt); - struct i2ohba *i2ohba = ADDR2I2OHBA(ap); - i2o_tid_scsi_ent_t **map = i2ohba->i2ohba_tgt_id_map; - uint8_t tgt = ap->a_target; - - if (map[tgt] != NULL) { - if (sp->cmd_flags & CFLAG_DMAVALID) { - /* - * Free the mapping. - */ - sp->cmd_flags &= ~CFLAG_DMAVALID; - if (ddi_dma_unbind_handle(sp->cmd_dmahandle) - != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_scsi_dmafree: " - "ddi_dma_unbind_handle() for dataseg" - " failed"); - /*NOTREACHED*/ - } -#ifdef I2OHBA_DEBUG - ddi_dma_buf_unbind++; -#endif - ddi_dma_free_handle(&sp->cmd_dmahandle); -#ifdef I2OHBA_DEBUG - ddi_dma_buf_free_hdl++; -#endif - sp->cmd_dmahandle = NULL; - } - } -} - -/* - * Function name: i2ohba_scsi_sync_pkt() - * - * Return Values: none - * Description : sync dma - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -/*ARGSUSED*/ -static void -i2ohba_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) -{ - int i; - struct i2ohba_cmd *sp = PKT2CMD(pkt); - struct i2ohba *i2ohba = ADDR2I2OHBA(ap); - i2o_tid_scsi_ent_t **map = i2ohba->i2ohba_tgt_id_map; - uint8_t tgt = ap->a_target; - - if (map[tgt] != NULL) { - if (sp->cmd_flags & CFLAG_DMAVALID) { - i = ddi_dma_sync(sp->cmd_dmahandle, sp->cmd_dma_offset, - sp->cmd_dma_len, - (sp->cmd_flags & CFLAG_DMASEND) ? - DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); - if (i != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_scsi_sync_pkt: sync pkt failed"); - } - } - } -} - - -/* - * routine for reset notification setup, to register or cancel. - */ -static int -i2ohba_scsi_reset_notify(struct scsi_address *ap, int flag, -void (*callback)(caddr_t), caddr_t arg) -{ - struct i2ohba *i2ohba = ADDR2I2OHBA(ap); - return (scsi_hba_reset_notify_setup(ap, flag, callback, arg, - I2OHBA_REQ_MUTEX(i2ohba), &i2ohba->i2ohba_reset_notify_listf)); -} - -/* - * Function name : i2ohba_scsi_start() - * - * Return Values : TRAN_FATAL_ERROR - i2o has been shutdown - * TRAN_BUSY - request queue is full - * TRAN_ACCEPT - pkt has been submitted to i2o - * - * Description : init pkt, start the request - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -static int -i2ohba_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) -{ - struct i2ohba_cmd *sp = PKT2CMD(pkt); - int rval = TRAN_ACCEPT; - struct i2ohba *i2ohba = ADDR2I2OHBA(ap); - dev_info_t *dip = (PKT2I2OHBA(pkt))->i2ohba_dip; - i2o_tid_scsi_ent_t **tgtmap = i2ohba->i2ohba_tgt_id_map; - i2o_scsi_scb_execute_message_t *req; - i2o_sge_chain_element_t *sgl; - i2o_sge_ignore_element_t *sgl2; - i2o_msg_handle_t msg_handle; - i2o_sge_chain_element_t *cpsgl; - ddi_acc_handle_t acc_handle; - clock_t cur_lbolt; - uint16_t tid; - uint16_t flags = 0, msgsize; - int i, val, bound = 0; - size_t sglen; - uint_t count; - - - ASSERT(I2OHBA_MUTEX_OWNED(i2ohba) == 0 || ddi_in_panic()); - - /* - * if we have a shutdown, return packet - */ - if (i2ohba->i2ohba_shutdown) { - return (TRAN_FATAL_ERROR); - } - - if (i2ohba->i2ohba_throttle) { - return (TRAN_BUSY); - } - /* - * if the target id is not in our map, don't bother composing - * the message, return fail - */ - if (tgtmap[TGT(sp)] == NULL) { - return (TRAN_FATAL_ERROR); - } else { - tid = tgtmap[TGT(sp)]->tid; - } - - i2ohba->i2ohba_counter++; - if (i2ohba->i2ohba_counter > 64) { - DEBUGF(1, (CE_CONT, "i2ohba_counter > 64\n")); - DEBUGF(1, (CE_CONT, "sp = %p\n", (void *)sp)); - i2ohba->i2ohba_counter--; - return (TRAN_BUSY); - } - - ASSERT(!(sp->cmd_flags & CFLAG_IN_TRANSPORT)); - sp->cmd_flags = (sp->cmd_flags & ~CFLAG_TRANFLAG) | - CFLAG_IN_TRANSPORT; - pkt->pkt_reason = CMD_CMPLT; - - /* - * Set up request in i2ohba_reqhead area so it is ready to - * go once we have the request mutex, - * The reason we don't allocate the msg buffer in scsi_init_pkt - * is that the msg buffer is a resource from the FIFO of the IOP - * we don't want to give that ptr around - */ - - if (i2o_msg_alloc(i2ohba->i2ohba_iophdl, I2O_MSG_DONTWAIT, - NULL, (void *)&req, &msg_handle, &acc_handle) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_scsi_start: " - " i2o_msg_alloc failed"); - sp->cmd_flags = (sp->cmd_flags & ~CFLAG_IN_TRANSPORT); - pkt->pkt_reason = 0; - i2ohba->i2ohba_counter--; - return (TRAN_BUSY); - } - - - /* - * Constructed a scsi_scb_execute_message - */ - - /* StdMessageFrame */ - req->StdMessageFrame.VersionOffset = 0xA1; - req->StdMessageFrame.MsgFlags = 0; - - if (sp->cmd_flags & CFLAG_DMAVALID) { - msgsize = ((sizeof (i2o_scsi_scb_execute_message_t) - - sizeof (i2o_sg_element_t) + - sizeof (i2o_sge_chain_element_t) + - sizeof (i2o_sge_ignore_element_t)) >> 2); - } else { - msgsize = ((sizeof (i2o_scsi_scb_execute_message_t) - - sizeof (i2o_sg_element_t)) >> 2); - } - - /* - * To get actual allocation msg size - */ - ASSERT(msgsize <= ddi_get16(acc_handle, - &req->StdMessageFrame.MessageSize)); - - ddi_put16(acc_handle, &req->StdMessageFrame.MessageSize, msgsize); - put_msg_TargetAddress(&req->StdMessageFrame, tid, acc_handle); - put_msg_InitiatorAddress(&req->StdMessageFrame, I2O_OSM_TID, - acc_handle); - put_msg_Function(&req->StdMessageFrame, I2O_SCSI_SCB_EXEC, acc_handle); - ddi_put32(acc_handle, - (uint32_t *)&req->StdMessageFrame.InitiatorContext, - (uint32_t)i2ohba_callback); - - /* TransactionContext */ - ddi_put32(acc_handle, &req->TransactionContext, - (uint32_t)(uintptr_t)sp); - - /* Set up CDB in the request */ - - bzero(req->CDB, I2O_SCSI_CDB_LENGTH); - if (sp->cmd_cdblen > I2O_SCSI_CDB_LENGTH) { - req->CDBLength = I2O_SCSI_CDB_LENGTH; - } else { - req->CDBLength = sp->cmd_cdblen; - } - bcopy(pkt->pkt_cdbp, req->CDB, sp->cmd_cdblen); - bcopy(pkt->pkt_cdbp, sp->cmd_cdb, sp->cmd_cdblen); - -#ifdef I2OHBA_DEBUG - if (sp->cmd_cdblen == 0x6) { - DEBUGF(1, (CE_CONT, "%d: %x %x %x %x %x %x\n", - sp->cmd_cdblen, - pkt->pkt_cdbp[0], pkt->pkt_cdbp[1], - pkt->pkt_cdbp[2], pkt->pkt_cdbp[3], - pkt->pkt_cdbp[4], pkt->pkt_cdbp[5])); - } else { - DEBUGF(1, (CE_CONT, "10: %x %x %x %x %x %x %x %x %x %x\n", - pkt->pkt_cdbp[0], pkt->pkt_cdbp[1], - pkt->pkt_cdbp[2], pkt->pkt_cdbp[3], - pkt->pkt_cdbp[4], pkt->pkt_cdbp[5], - pkt->pkt_cdbp[6], pkt->pkt_cdbp[7], - pkt->pkt_cdbp[8], pkt->pkt_cdbp[9])); - } -#endif - - DEBUGF(1, (CE_CONT, "pkt_flags = 0x%x\n", pkt->pkt_flags)); - /* Tag queuing */ - if (pkt->pkt_flags & FLAG_STAG) - flags |= I2O_SCB_FLAG_SIMPLE_QUEUE_TAG; - - else if (pkt->pkt_flags & FLAG_OTAG) - flags |= I2O_SCB_FLAG_ORDERED_QUEUE_TAG; - - else if (pkt->pkt_flags & FLAG_HTAG) - flags |= I2O_SCB_FLAG_HEAD_QUEUE_TAG; - - else if (pkt->pkt_flags & FLAG_ACA) - flags |= I2O_SCB_FLAG_ACA_QUEUE_TAG; - - if ((pkt->pkt_flags & FLAG_SENSING) || - (i2ohba->i2ohba_cap[TGT(sp)] & I2OHBA_CAP_AUTOSENSE)) - flags |= I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE; - - /* DISCONNECT enable by default especially with TAGQ */ - if (pkt->pkt_flags & FLAG_NODISCON) - flags &= ~I2O_SCB_FLAG_ENABLE_DISCONNECT; - else - flags |= I2O_SCB_FLAG_ENABLE_DISCONNECT; - - if (sp->cmd_flags & CFLAG_DMASEND) { - flags |= I2O_SCB_FLAG_XFER_TO_DEVICE; - } else { - flags |= I2O_SCB_FLAG_XFER_FROM_DEVICE; - } - - ddi_put16(acc_handle, &req->SCBFlags, flags); - DEBUGF(1, (CE_CONT, "SCBflags = 0x%x\n", flags)); - - /* - * All msg are using chain pointer. - * Setup dma transfers data segments. - */ - - sgl = (i2o_sge_chain_element_t *)&req->SGL; - sgl2 = (i2o_sge_ignore_element_t *)((caddr_t)sgl + - sizeof (i2o_sge_chain_element_t)); - if (sp->cmd_flags & CFLAG_DMAVALID) { - - if (sp->cmd_flags & CFLAG_CMDIOPB) { - (void) ddi_dma_sync(sp->cmd_dmahandle, - sp->cmd_dma_offset, sp->cmd_dma_len, - DDI_DMA_SYNC_FORDEV); - } - - ASSERT(sp->cmd_cookiecnt > 0); - - /* size of the next SGL chain elements list */ - sglen = sp->cmd_cookiecnt * sizeof (i2o_sge_chain_element_t); - - /* flags */ - put_flags_count_Flags(&sgl->FlagsCount, - I2O_SGL_FLAGS_CHAIN_POINTER_ELEMENT, acc_handle); - - /* - * instead of allocating a chuck of dma - * address here like isp driver, the - * trade of speed vs managing the free - * memory list. I don't want this - * to become kmem_alloc functions. - */ - if (ddi_dma_alloc_handle(dip, &i2ohba_dmasgl_attr, - DDI_DMA_DONTWAIT, NULL, &sp->sglbuf_dmahandle) - != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_scsi_start: " - "cannot allocate SGL's chain buffer handle"); - goto cleanup; - } - bound++; -#ifdef I2OHBA_DEBUG - ddi_dma_alloc_hdl++; -#endif - - if (ddi_dma_mem_alloc(sp->sglbuf_dmahandle, (size_t) - sglen, &dev_attr, DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, - NULL, (caddr_t *)&sp->sglbuf, &sp->sglrlen, - &sp->sglbuf_dmaacchandle) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_scsi_start: " - "cannot allocate SGL's chain buffer memory"); - goto cleanup; - } - bound++; -#ifdef I2OHBA_DEBUG - ddi_dma_alloc_mem++; -#endif - - /* - * we passed in the sgl real length in transaction - * context because we need it to free the dma, - * but we set the chain element header with sglen - */ - put_flags_count_Count(&sgl->FlagsCount, sglen, acc_handle); - - put_flags_count_Flags(&sgl2->FlagsCount, - I2O_SGL_FLAGS_IGNORE_ELEMENT | - I2O_SGL_FLAGS_LAST_ELEMENT, acc_handle); - - put_flags_count_Count(&sgl2->FlagsCount, 0x1, acc_handle); - - /* fill in the SGL chain headers */ - sp->cmd_xfercount = 0; - cpsgl = (i2o_sge_chain_element_t *)sp->sglbuf; - - for (i = 0; i < sp->cmd_cookiecnt; i++, cpsgl++) { - - put_flags_count_Flags(&cpsgl->FlagsCount, - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT, - sp->sglbuf_dmaacchandle); - - put_flags_count_Count(&cpsgl->FlagsCount, - sp->cmd_dmacookies[i].dmac_size, - sp->sglbuf_dmaacchandle); - - ddi_put32(sp->sglbuf_dmaacchandle, - &cpsgl->PhysicalAddress, - sp->cmd_dmacookies[i].dmac_address); - - sp->cmd_xfercount += - sp->cmd_dmacookies[i].dmac_size; - } - - DEBUGF(3, (CE_CONT, "cookiecnt is %x, ncookie is %x," - "cookie# is %d\n", sp->cmd_cookiecnt, sp->cmd_ncookies, - sp->cmd_cookie)); - DEBUGF(3, (CE_CONT, "cmd_xfercount is %lx\n", - sp->cmd_xfercount)); - - - /* mark the last chain pointer header as the last one */ - - cpsgl--; - put_flags_count_Flags(&cpsgl->FlagsCount, - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT | - I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER, - sp->sglbuf_dmaacchandle); - - if (ddi_dma_addr_bind_handle(sp->sglbuf_dmahandle, NULL, - (caddr_t)sp->sglbuf, sp->sglrlen, DDI_DMA_RDWR | - DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, NULL, - &sp->sglbuf_dmacookie, &count) != DDI_DMA_MAPPED) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_scsi_start: " - "cannot bind SGL's bind handle"); - goto cleanup; - } -#ifdef I2OHBA_DEBUG - ddi_dma_bind_hdl++; -#endif - - DEBUGF(1, (CE_CONT, "start: cmd_dmacount=%lx," - " cmd_xfercount=%lx\n", - sp->cmd_dmacount, sp->cmd_xfercount)); - - ddi_put32(acc_handle, &req->ByteCount, sp->cmd_xfercount); - - ddi_put32(acc_handle, &sgl->PhysicalAddress, - (uint32_t)sp->sglbuf_dmacookie.dmac_address); - - } else { - ddi_put32(acc_handle, &req->ByteCount, 0); - put_flags_count_Flags(&sgl->FlagsCount, 0, acc_handle); - put_flags_count_Count(&sgl->FlagsCount, 0, acc_handle); - put_flags_count_Flags(&sgl2->FlagsCount, 0, acc_handle); - put_flags_count_Count(&sgl2->FlagsCount, 0, acc_handle); - } - - /* - * calculate deadline from pkt_time - * Instead of multiplying by 100 (ie. HZ), we multiply by 128 so - * we can shift and at the same time have a 28% grace period - * we ignore the rare case of pkt_time == 0 and deal with it - * in i2ohba_i_watch() - */ - cur_lbolt = ddi_get_lbolt(); - sp->cmd_deadline = cur_lbolt + (clock_t)(pkt->pkt_time * 256); - - I2OHBA_MUTEX_ENTER(i2ohba); - (void) i2ohba_i_req_insert(i2ohba, sp); - I2OHBA_MUTEX_EXIT(i2ohba); - /* - * Start the cmd. If NO_INTR, must wait for cmd reply/completion. - */ - if ((pkt->pkt_flags & FLAG_NOINTR) == 0) { - - /* - * need a list (or some sort of queue) so that - * when we need to flash the queue, ie: SCSI_BUS_RESET - * we'll have a way to do it (link list) - */ - val = i2o_msg_send(i2ohba->i2ohba_iophdl, req, msg_handle); - if (val != DDI_SUCCESS) - rval = TRAN_BUSY; /* I/O couldnot be started */ - } else { - val = i2o_msg_send(i2ohba->i2ohba_iophdl, req, msg_handle); - /* poll command */ - if (val == DDI_SUCCESS) { - i2ohba_i_polled_cmd_start(i2ohba, sp); - } else { - rval = TRAN_BUSY; - } - } - return (rval); - -cleanup: - - if (sp) { - if (bound) { - (void) ddi_dma_unbind_handle(sp->sglbuf_dmahandle); -#ifdef I2OHBA_DEBUG - ddi_dma_unbind++; -#endif - if (bound > 1) { - ddi_dma_mem_free(&sp->sglbuf_dmaacchandle); -#ifdef I2OHBA_DEBUG - ddi_dma_free_mem++; -#endif - } - ddi_dma_free_handle(&sp->sglbuf_dmahandle); -#ifdef I2OHBA_DEBUG - ddi_dma_bind_free++; -#endif - } - - sp->cmd_flags = (sp->cmd_flags & ~CFLAG_IN_TRANSPORT); - i2ohba->i2ohba_counter--; - pkt->pkt_reason = 0; - } - - /* return MFA to IOP */ - if (req) { - req->StdMessageFrame.VersionOffset = 0; - req->StdMessageFrame.MsgFlags = 0; - ddi_put16(acc_handle, &req->StdMessageFrame.MessageSize, 3); - put_msg_TargetAddress(&req->StdMessageFrame, 0, acc_handle); - put_msg_InitiatorAddress(&req->StdMessageFrame, 0, acc_handle); - put_msg_Function(&req->StdMessageFrame, I2O_UTIL_NOP, - acc_handle); - (void) i2o_msg_send(i2ohba->i2ohba_iophdl, req, msg_handle); - } - - ASSERT(I2OHBA_MUTEX_OWNED(i2ohba) == 0 || ddi_in_panic()); - return (TRAN_BUSY); -} - - -/* - * Function name : i2ohba_i_req_insert() - * - * Return Values : void - * - * Usage : called by i2ohba_scsi_start(). - * - * Description : Insert the i2ohba_cmd into the double - * link list in FIFO fashion. - * - * Context : called by SCSA frame work. - */ -static void -i2ohba_i_req_insert(struct i2ohba *i2ohba, struct i2ohba_cmd *sp) -{ - struct i2ohba_cmd *head = i2ohba->i2ohba_reqhead; - - sp->cmd_forw = head; - if (head != NULL) { - i2ohba->i2ohba_reqhead->cmd_backw = sp; - } else { - i2ohba->i2ohba_reqtail = sp; - } - i2ohba->i2ohba_reqhead = sp; - sp->cmd_backw = NULL; - -} - - -/* - * Function name : i2ohba_i_req_remove() - * - * Return Values : void - * - * Usage : called by i2ohba_callback(). - * called by i2ohba_scsi_start() if i2o_msg_send() - * failed. - * Description : remove a i2ohba_cmd from the double link list - * - * Context : called by SCSA frame work. - */ -static void -i2ohba_i_req_remove(struct i2ohba *i2ohba, struct i2ohba_cmd *sp) -{ - struct i2ohba_cmd *tail = i2ohba->i2ohba_reqtail; - struct i2ohba_cmd *tmp; - - for (tmp = tail; tmp != NULL; tmp = tmp->cmd_backw) { - if (tmp == sp) { - if (tmp->cmd_backw) - tmp->cmd_backw->cmd_forw = tmp->cmd_forw; - else - i2ohba->i2ohba_reqhead = tmp->cmd_forw; - - if (tmp->cmd_forw) - tmp->cmd_forw->cmd_backw = tmp->cmd_backw; - else - i2ohba->i2ohba_reqtail = tmp->cmd_backw; - - tmp->cmd_backw = NULL; - tmp->cmd_forw = NULL; - break; - - } - } -} - -/* - * Function name : i2ohba_callback() - * - * Return Values : None - * - * Context: : called by interrupt thread. - */ - -void -i2ohba_callback(i2o_message_frame_t *msg, ddi_acc_handle_t acc_handle) -{ - - i2o_single_reply_message_frame_t *reply; - struct i2ohba *i2ohba; - struct scsi_pkt *pkt; - struct i2ohba_cmd *sp; - uint8_t reqstatus; - - reply = (i2o_single_reply_message_frame_t *)msg; - - - ASSERT(I2O_SCSI_SCB_EXEC == get_msg_Function( - &reply->StdMessageFrame, acc_handle)); - - sp = (struct i2ohba_cmd *)(uintptr_t)ddi_get32(acc_handle, - &reply->TransactionContext); - - ASSERT(sp); - - i2ohba = CMD2I2OHBA(sp); - I2OHBA_MUTEX_ENTER(i2ohba); - (void) i2ohba_i_req_remove(i2ohba, sp); - I2OHBA_MUTEX_EXIT(i2ohba); - - if (sp->cmd_dmahandle) { - (void) ddi_dma_sync(sp->cmd_dmahandle, - sp->cmd_dma_offset, sp->cmd_dma_len, - DDI_DMA_SYNC_FORKERNEL); - } - - reqstatus = ddi_get8(acc_handle, &reply->ReqStatus); - DEBUGF(1, (CE_CONT, "reqstatus %x\n", reqstatus)); - pkt = CMD2PKT(sp); - - /* - * First filter the reqstatus - * check for any special errors - */ - switch (reqstatus) { - - case I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER: - /* - * With paritial transfer, we want to make - * sure it is an USCSI cmd - */ - if ((pkt->pkt_flags >> 16) == 0) - pkt->pkt_reason = CMD_TRAN_ERR; - - sp->cmd_flags |= CFLAG_FINISHED; - i2ohba_i_pkt_comp(reply, acc_handle, sp); - - return; - - case I2O_REPLY_STATUS_SUCCESS: - /* - * With successful completetion, only the ReqStatus - * field is set to reflect sucessful completion, the - * DetailedStatusCode is set to zero, the TransferCount - * field indicates the actual amount of data transferred. - * There is no StatusData. - */ - - sp->cmd_flags |= CFLAG_FINISHED; - i2ohba_i_pkt_comp(reply, acc_handle, sp); - - return; - - /* XXLWXX Error code handling */ - case I2O_REPLY_STATUS_ABORT_DIRTY: - case I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER: - case I2O_REPLY_STATUS_ERROR_DIRTY: - case I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER: - case I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY: - case I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER: - case I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER: - case I2O_REPLY_STATUS_PROGRESS_REPORT: - /* - * If message has failed due to aborted by hosts, - * error in execution, due to system command or reconfig. - * failed the request. - */ - case I2O_REPLY_STATUS_TRANSACTION_ERROR: - default: - pkt->pkt_reason = CMD_TRAN_ERR; - sp->cmd_flags |= CFLAG_FINISHED; - i2ohba_i_pkt_comp(reply, acc_handle, sp); -#ifdef I2OHBA_DEBUG - DEBUGF(1, (CE_CONT, - "?i2ohba_callback: Reply Failed")); -#endif - break; - - } -} - -/* - * Function name : i2ohba_i_pkt_complete() - * - * Return Values : none - * - * Description : - * callback into target driver - * argument is a NULL-terminated list of packets - * copy over stuff from response packet - * - * Context : Can be called by interrupt thread. - */ -static void -i2ohba_i_pkt_comp(i2o_single_reply_message_frame_t *reply, ddi_acc_handle_t - acc_handle, struct i2ohba_cmd *sp) -{ - i2o_scsi_success_reply_message_frame_t *replysuc; - i2o_scsi_error_reply_message_frame_t *replyerr; - struct i2ohba *i2ohba; - struct scsi_pkt *pkt; - uint32_t transcount; - uint32_t autocount; - uint16_t adptrstatus; - uint16_t detailstat; - uint16_t messagesize; - uint8_t devstatus; - - i2ohba = CMD2I2OHBA(sp); - ASSERT(I2OHBA_MUTEX_OWNED(i2ohba) == 0 || ddi_in_panic()); - - pkt = CMD2PKT(sp); - - ASSERT(sp->cmd_flags & CFLAG_FINISHED); - - if (sp->cmd_flags & CFLAG_DMAVALID) { - if (ddi_dma_unbind_handle(sp->sglbuf_dmahandle) != - DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_scsi_dmafree: " - "ddi_dma_unbind_handle() for sglbuf failed"); - /*NOTREACHED*/ - } -#ifdef I2OHBA_DEBUG - ddi_dma_unbind++; -#endif - ddi_dma_mem_free(&sp->sglbuf_dmaacchandle); -#ifdef I2OHBA_DEBUG - ddi_dma_free_mem++; -#endif - ddi_dma_free_handle(&sp->sglbuf_dmahandle); -#ifdef I2OHBA_DEBUG - ddi_dma_bind_free++; -#endif - sp->sglbuf_dmahandle = NULL; - } - - replysuc = (i2o_scsi_success_reply_message_frame_t *)reply; - - detailstat = ddi_get16(acc_handle, &reply->DetailedStatusCode); - devstatus = (uint8_t)(detailstat & I2O_SCSI_DEVICE_DSC_MASK); - /* this is a workaround for 0x3 and 0x9 LSB is being ORed */ - devstatus = devstatus & 0xfe; - DEBUGF(1, (CE_CONT, "devstatus %x\n", devstatus)); - adptrstatus = detailstat & I2O_SCSI_HBA_DSC_MASK; - DEBUGF(1, (CE_CONT, "adptrstatus %x\n", adptrstatus)); - - transcount = ddi_get32(acc_handle, &replysuc->TransferCount); - - if (detailstat == 0) { - pkt->pkt_scbp[0] = - (uint8_t)(detailstat & I2O_SCSI_DEVICE_DSC_MASK); - pkt->pkt_reason = CMD_CMPLT; - pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET | - STATE_SENT_CMD | STATE_XFERRED_DATA; - pkt->pkt_statistics = 0; - pkt->pkt_resid = sp->cmd_xfercount - transcount; - } else { - replyerr = (i2o_scsi_error_reply_message_frame_t *)reply; - - /* - * devstatus: SCSI_SUCESS 0, SCSI_CHECK_COND 2, - * SCSI_BUSY 8, SCSI_RES_CONFLICT 18, - * SCSI_CMD_TERM 22, SCSI_TASK_SET_FULL 28, - * SCSI_ACA_ACTIVE 30 - */ - messagesize = ddi_get16(acc_handle, - &replyerr->StdReplyFrame.StdMessageFrame.MessageSize); - - pkt->pkt_scbp[0] = devstatus; - - if (devstatus == I2O_SCSI_DSC_CHECK_CONDITION) { - pkt->pkt_reason = CMD_CMPLT; - pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET | - STATE_SENT_CMD | STATE_XFERRED_DATA; - pkt->pkt_statistics = 0; - goto arqchk; - } - - /* SYM HDM problem, can't recognized USCSI cmd well */ - if ((devstatus == I2O_SCSI_DSC_BUSY) && - (transcount != 0) && ((pkt->pkt_flags >> 16) != 0)) { - pkt->pkt_reason = CMD_CMPLT; - pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET | - STATE_SENT_CMD | STATE_XFERRED_DATA; - pkt->pkt_statistics = 0; - pkt->pkt_resid = sp->cmd_xfercount - transcount; - pkt->pkt_scbp[0] = STATUS_GOOD; - goto done; - } - - - switch (adptrstatus) { - - case I2O_SCSI_HBA_DSC_AUTOSENSE_FAILED: - pkt->pkt_reason = CMD_INCOMPLETE; - pkt->pkt_state |= STATE_ARQ_DONE; - break; - - /* bus reset */ - case I2O_SCSI_HBA_DSC_SCSI_BUS_RESET: - pkt->pkt_reason = CMD_RESET; - pkt->pkt_statistics |= STAT_BUS_RESET; - /* Do we need to call notify_callback? */ - scsi_hba_reset_notify_callback( - I2OHBA_REQ_MUTEX(i2ohba), - &i2ohba->i2ohba_reset_notify_listf); - break; - - /* cmd terminated */ - case I2O_SCSI_HBA_DSC_REQUEST_TERMINATED: - pkt->pkt_reason = CMD_TERMINATED; - - pkt->pkt_statistics |= STAT_TERMINATED; - break; - - /* request aborted */ - case I2O_SCSI_HBA_DSC_NO_NEXUS: - pkt->pkt_reason = CMD_ABORTED; - pkt->pkt_statistics |= STAT_ABORTED; - break; - - /* parity error */ - case I2O_SCSI_HBA_DSC_PARITY_ERROR_FAILURE: - pkt->pkt_reason = CMD_TRAN_ERR; - pkt->pkt_statistics |= STAT_PERR; - i2ohba_i_log(NULL, CE_WARN, "?Parity Error"); - break; - - /* data overrun */ - case I2O_SCSI_HBA_DSC_DATA_OVERRUN: - pkt->pkt_reason = CMD_DATA_OVR; - pkt->pkt_state |= STATE_GOT_BUS | - STATE_GOT_TARGET | STATE_SENT_CMD | - STATE_XFERRED_DATA; - break; - - /* cmd complete with error */ - case I2O_SCSI_HBA_DSC_LUN_ALREADY_ENABLED: - case I2O_SCSI_HBA_DSC_COMPLETE_WITH_ERROR: - /* devstatus should be busy/checkcond */ - pkt->pkt_reason = CMD_CMPLT; - break; - - /* cmd aborted by request or aborted by time */ - case I2O_SCSI_HBA_DSC_REQUEST_ABORTED: - if (sp->cmd_flags & CFLAG_DELAY_TIMEOUT) { - pkt->pkt_reason = CMD_TIMEOUT; - pkt->pkt_statistics |= STAT_TIMEOUT - | STAT_ABORTED; - } else { - pkt->pkt_reason = CMD_ABORTED; - pkt->pkt_statistics |= STAT_ABORTED; - } - break; - - /* cmd timeout */ - case I2O_SCSI_HBA_DSC_COMMAND_TIMEOUT: - pkt->pkt_reason = CMD_TIMEOUT; - pkt->pkt_statistics |= STAT_TIMEOUT; - break; - - /* CDB received */ - case I2O_SCSI_HBA_DSC_CDB_RECEIVED: - pkt->pkt_reason = CMD_INCOMPLETE; - pkt->pkt_state |= STATE_SENT_CMD | - STATE_GOT_BUS | STATE_GOT_TARGET | - STATE_XFERRED_DATA; - break; - - /* device reset msg send */ - case I2O_SCSI_HBA_DSC_BDR_MESSAGE_SENT: - pkt->pkt_reason = CMD_RESET; - pkt->pkt_statistics |= STAT_DEV_RESET; - break; - - /* unexpected bus free */ - case I2O_SCSI_HBA_DSC_UNEXPECTED_BUS_FREE: - pkt->pkt_reason = CMD_UNX_BUS_FREE; - break; - - /* cmd failed, transport error */ - case I2O_SCSI_HBA_DSC_ADAPTER_BUSY: - case I2O_SCSI_HBA_DSC_SEQUENCE_FAILURE: - case I2O_SCSI_HBA_DSC_BUS_BUSY: - case I2O_SCSI_HBA_DSC_QUEUE_FROZEN: - case I2O_SCSI_HBA_DSC_UNABLE_TO_ABORT: - case I2O_SCSI_HBA_DSC_UNABLE_TO_TERMINATE: - case I2O_SCSI_HBA_DSC_RESOURCE_UNAVAILABLE: - pkt->pkt_reason = CMD_TRAN_ERR; - break; - - /* failed command, retry? */ - case I2O_SCSI_HBA_DSC_REQUEST_INVALID: - case I2O_SCSI_HBA_DSC_PATH_INVALID: - case I2O_SCSI_HBA_DSC_INVALID_CDB: - case I2O_SCSI_HBA_DSC_LUN_INVALID: - case I2O_SCSI_HBA_DSC_SELECTION_TIMEOUT: - pkt->pkt_state |= STATE_GOT_BUS; - pkt->pkt_reason = CMD_INCOMPLETE; - break; - - case I2O_SCSI_HBA_DSC_DEVICE_NOT_PRESENT: - case I2O_SCSI_HBA_DSC_FUNCTION_UNAVAILABLE: - pkt->pkt_reason = CMD_INCOMPLETE; - break; - - /* what? NO adapter! shutdown now! */ - case I2O_SCSI_HBA_DSC_NO_ADAPTER: - i2ohba->i2ohba_shutdown = 1; - break; - - case I2O_SCSI_HBA_DSC_SCSI_TID_INVALID: - case I2O_SCSI_HBA_DSC_SCSI_IID_INVALID: - default: /* failed cmd, retry */ - pkt->pkt_state |= STATE_GOT_BUS; - pkt->pkt_reason = CMD_TRAN_ERR; - break; - - - } - - pkt->pkt_resid = sp->cmd_xfercount; - - /* - * was there auto request sense info? - */ -arqchk: if (messagesize > - sizeof (i2o_scsi_success_reply_message_frame_t)) { - autocount = ddi_get32(acc_handle, - &replyerr->AutoSenseTransferCount); - - /* currently uses the DATA_IN_MESSAGE, only 40 bytes */ - if (autocount) { - pkt->pkt_state |= STATE_ARQ_DONE; - i2ohba_i_handle_arq(replyerr, sp, autocount); - } - } - - } - - -done: DEBUGF(1, (CE_CONT, "transfer=0x%x, resid=0x%lx\n", transcount, - pkt->pkt_resid)); - - /* - * if data was xferred and this was an IOPB, we need - * to do a dma sync - */ - if ((sp->cmd_flags & CFLAG_CMDIOPB) && - (pkt->pkt_state & STATE_XFERRED_DATA)) { - (void) ddi_dma_sync(sp->cmd_dmahandle, - sp->cmd_dma_offset, sp->cmd_dma_len, - DDI_DMA_SYNC_FORCPU); - } - - - ASSERT(sp->cmd_flags & CFLAG_IN_TRANSPORT); - ASSERT(sp->cmd_flags & CFLAG_FINISHED); - ASSERT((sp->cmd_flags & CFLAG_COMPLETED) == 0); - - sp->cmd_flags = ((sp->cmd_flags & ~CFLAG_IN_TRANSPORT) & - ~CFLAG_DELAY_TIMEOUT) | CFLAG_COMPLETED; - i2ohba->i2ohba_counter--; - - /* - * Call packet completion routine if FLAG_NOINTR is not set. - * If FLAG_NOINTR is set turning on CFLAG_COMPLETED in line - * above will cause busy wait loop in - * i2ohba_i_polled_cmd_start() to exit. - */ - if (((pkt->pkt_flags & FLAG_NOINTR) == 0) && - pkt->pkt_comp) { - (*pkt->pkt_comp)(pkt); - } - - ASSERT(I2OHBA_MUTEX_OWNED(i2ohba) == 0 || ddi_in_panic()); -} - - -/* - * Function name : i2ohba_i_handle_arq() - * - * Description : called on an autorequest sense condition, sets up arqstat - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -static void -i2ohba_i_handle_arq(i2o_scsi_error_reply_message_frame_t *replyerr, - struct i2ohba_cmd *sp, int aqcount) -{ - char status; - struct scsi_pkt *pkt = CMD2PKT(sp); - - if (sp->cmd_scblen >= sizeof (struct scsi_arq_status)) { - struct scsi_arq_status *arqstat; - - DEBUGF(1, (CE_CONT, "tgt %d.%d: auto request sense", - TGT(sp), LUN(sp))); - - /* clear the pkt_scbp struct */ - arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp); - status = pkt->pkt_scbp[0]; - bzero(arqstat, sizeof (struct scsi_arq_status)); - - /* - * I2O does not provide statistics for request sense, - * so use same statistics as the original cmd. - */ - arqstat->sts_rqpkt_statistics = pkt->pkt_statistics; - arqstat->sts_rqpkt_state = - (STATE_GOT_BUS | STATE_GOT_TARGET | - STATE_SENT_CMD | STATE_XFERRED_DATA | STATE_GOT_STATUS); - if (aqcount < sizeof (struct scsi_extended_sense)) { - arqstat->sts_rqpkt_resid = - sizeof (struct scsi_extended_sense) - aqcount; - - } - bcopy(replyerr->SenseData, - &arqstat->sts_sensedata, - (sizeof (struct scsi_extended_sense) < - I2O_SCSI_SENSE_DATA_SZ) ? - sizeof (struct scsi_extended_sense) : - I2O_SCSI_SENSE_DATA_SZ); - - /* - * restore status which was wiped out by bzero - */ - pkt->pkt_scbp[0] = status; - - DEBUGF(1, (CE_CONT, "arq: %x %x %x %x %x %x %x", - replyerr->SenseData[0], replyerr->SenseData[1], - replyerr->SenseData[2], replyerr->SenseData[3], - replyerr->SenseData[4], replyerr->SenseData[5], - replyerr->SenseData[6])); - return; - } - /* - * Failed cmd auto sense data; can't copy over ARQ data, - */ - DEBUGF(1, (CE_CONT, "Failed cmd, possible sense data")); - DEBUGF(1, (CE_CONT, "arq: %x %x %x %x %x %x %x", - replyerr->SenseData[0], replyerr->SenseData[1], - replyerr->SenseData[2], replyerr->SenseData[3], - replyerr->SenseData[4], replyerr->SenseData[5], - replyerr->SenseData[6])); -} - - -/* - * Function name : i2ohba_i_polled_cmd_start() - * - * Return Values : TRAN_ACCEPT if transaction was accepted - * TRAN_BUSY if I/O could not be started - * TRAN_ACCEPT if I/O timed out, pkt fields indicate error - * - * Description : Busy waits for I/O to complete or timeout. - * NOTE: This function returns void because the cmd - * has already started in scsi_start() before this - * function is called. So no need to return rval. - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -static void -i2ohba_i_polled_cmd_start(struct i2ohba *i2ohba, struct i2ohba_cmd *sp) -{ - int delay_loops; - struct scsi_pkt *pkt = CMD2PKT(sp); - - ASSERT(I2OHBA_MUTEX_OWNED(i2ohba) == 0 || ddi_in_panic()); - - /* - * set timeout to SCSI_POLL_TIMEOUT for non-polling - * commands that do not have this field set - */ - if (pkt->pkt_time == 0) { - pkt->pkt_time = SCSI_POLL_TIMEOUT; - } - - ASSERT(pkt->pkt_flags & FLAG_NOINTR); - - delay_loops = I2OHBA_TIMEOUT_DELAY( - (pkt->pkt_time + (2 * I2OHBA_GRACE)), - I2OHBA_NOINTR_POLL_DELAY_TIME); - - /* - * busy wait for command to finish - * ie. till CFLAG_COMPLETED is set - */ - while ((sp->cmd_flags & CFLAG_COMPLETED) == 0) { - drv_usecwait(I2OHBA_NOINTR_POLL_DELAY_TIME); - if (--delay_loops <= 0) { - - if ((i2ohba_scsi_reset(&pkt->pkt_address, - RESET_TARGET)) == 0) { - mutex_enter(I2OHBA_REQ_MUTEX(i2ohba)); - i2ohba_i_fatal_error(i2ohba); - mutex_exit(I2OHBA_REQ_MUTEX(i2ohba)); - } - pkt->pkt_reason = CMD_TIMEOUT; - pkt->pkt_statistics |= STAT_BUS_RESET | - STAT_TIMEOUT; - sp->cmd_flags = ((sp->cmd_flags & - ~CFLAG_IN_TRANSPORT) & ~CFLAG_DELAY_TIMEOUT) - | CFLAG_COMPLETED | CFLAG_FINISHED; - i2ohba->i2ohba_counter--; - break; - } - } - - ASSERT(I2OHBA_MUTEX_OWNED(i2ohba) == 0 || ddi_in_panic()); - -} - - - -/* - * Function name : i2ohba_i_watch() - * - * Return Values : none - * Description : I2OHBA deadman timer routine. - * - * Given that the i2ohba's request queue is double link list - * in FIFO fashion, the tail should be pointing at the oldest - * cmd. However, each command has different timeout value set - * by the target driver, if any of them has timeout then we - * will call fatal_error(). - * - * A hung i2ohba controller is detected by failure to complete - * cmds within a timeout interval (including grace period for - * i2ohba error recovery). All target error recovery is handled - * directly by the i2ohba. - * - * If i2ohba hungs, restart by resetting the i2ohba's HBA/BUS and - * flushing the double linked list (via i2ohba_i_qflush()). - * - * Tagged queueing gives us other headaches since we cannot know - * exactly when a command starts. For example, a command with a - * 2-hour timeout, will cause a second command with a 60-second timeout - * to be timed-out. We won't worry about it now, but will later - * - * Context : Can be called by timeout thread. - */ - -static void -i2ohba_i_watch(void *arg) -{ - struct i2ohba *i2ohba = (struct i2ohba *)arg; - clock_t cur_lbolt; - clock_t deadline; - struct i2ohba_cmd *sp; - struct scsi_pkt *pkt; - - - if (i2ohba->i2ohba_shutdown) { - return; - } - - I2OHBA_MUTEX_ENTER(i2ohba); - - if ((cur_lbolt = ddi_get_lbolt()) != 0) { - for (sp = i2ohba->i2ohba_reqtail; sp != NULL; - sp = sp->cmd_backw) { - pkt = CMD2PKT(sp); - deadline = sp->cmd_deadline; - if ((deadline - cur_lbolt <= 0) && (pkt->pkt_time)) { - if (!(sp->cmd_flags & CFLAG_DELAY_TIMEOUT)) { - /* report time out */ - i2ohba_i_log(NULL, CE_CONT, - "?i2ohba_i_watch: " - "Exend cmd timeout on target %d.%d", - TGT(sp), LUN(sp)); - /* reset timeout vaule for delay */ - sp->cmd_deadline = cur_lbolt + - (clock_t)(pkt->pkt_time * 192); - /* set DELAY_TIMEOUT indicator */ - sp->cmd_flags |= CFLAG_DELAY_TIMEOUT; - /* set throttle on */ - i2ohba->i2ohba_throttle++; - } else { - i2ohba_i_req_remove(i2ohba, sp); - pkt->pkt_reason = CMD_TIMEOUT; - pkt->pkt_statistics |= STAT_TIMEOUT; - sp->cmd_flags = ((sp->cmd_flags - & ~CFLAG_DELAY_TIMEOUT) - & ~CFLAG_IN_TRANSPORT) - | CFLAG_COMPLETED | CFLAG_FINISHED; - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_i_watch: " - "Cmd timeout on target %d.%d", - TGT(sp), LUN(sp)); - I2OHBA_MUTEX_EXIT(i2ohba); - if (((pkt->pkt_flags & FLAG_NOINTR) - == 0) && pkt->pkt_comp) { - (*pkt->pkt_comp)(pkt); - } - I2OHBA_MUTEX_ENTER(i2ohba); - } - } - } - - DEBUGF(2, (CE_CONT, "?throttle=%d", i2ohba->i2ohba_throttle)); - if ((i2ohba->i2ohba_reqtail == NULL) && - (i2ohba->i2ohba_reqhead == NULL)) { - i2ohba->i2ohba_throttle = 0; - } - - } - - if (i2ohba->i2ohba_need_prop_update) { - int i; - - for (i = 0; i < N_I2OHBA_TARGETS_WIDE; i++) { - if (i2ohba->i2ohba_need_prop_update & (1 << i)) { - i2ohba_i_update_props(i2ohba, i); - } - } - - i2ohba->i2ohba_need_prop_update = 0; - - } - - /* - * Set up next timeout - */ - i2ohba->i2ohba_timeout_id = timeout(i2ohba_i_watch, i2ohba, - i2ohba_tick); - I2OHBA_MUTEX_EXIT(i2ohba); -} - - - -/* - * Function name : i2ohba_i_fatal_error() - * - * Return Values : none - * - * Description : - * Isp fatal error recovery: - * Reset the i2o and flush the active queues and attempt restart. - * This should only happen in case of a firmware bug or hardware - * death. Flushing is from backup queue as I2O cannot be trusted. - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - * i2ohba_request_mutex is held. - */ -static void -i2ohba_i_fatal_error(struct i2ohba *i2ohba) -{ - /* - * hold off starting new requests by grabbing the request mutex - */ - ASSERT(I2OHBA_MUTEX_OWNED(i2ohba)); - - /* - * If shutdown flag is set than no need to do - * fatal error recovery. - */ - if (i2ohba->i2ohba_shutdown) { - return; - } - - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_i_fatal_error: " - "Fatal error, resetting interface"); - - i2ohba_i_print_state(i2ohba); - - (void) i2ohba_i_reset_interface(i2ohba, I2OHBA_FORCE_BUS_RESET); - - i2ohba_i_qflush(i2ohba, (uint16_t)0, (uint16_t)N_I2OHBA_TARGETS_WIDE); - - (void) scsi_hba_reset_notify_callback(I2OHBA_REQ_MUTEX(i2ohba), - &i2ohba->i2ohba_reset_notify_listf); - - ASSERT(I2OHBA_MUTEX_OWNED(i2ohba)); -} - - -/* - * Function name : i2ohba_i_qflush() - * - * Return Values : none - * Description : - * Flush i2ohba queues over range specified - * from start_tgt to end_tgt. Flushing goes from oldest to newest - * to preserve some cmd ordering. - * This is used for i2o crash recovery as normally i2o takes - * care of target or bus problems. - * - * Context : Can be called from different kernel process threads. - * i2ohba_i_fatal_error() - * i2ohba_i_reset_interface() - * Can be called by interrupt thread. - */ -static void -i2ohba_i_qflush(struct i2ohba *i2ohba, uint16_t start_tgt, uint16_t end_tgt) -{ - struct i2ohba_cmd *sp; - struct scsi_pkt *pkt; - - ASSERT(start_tgt <= end_tgt); - ASSERT(I2OHBA_MUTEX_OWNED(i2ohba)); - - - /* - * If flushing active queue, start with current free slot - * ie. oldest request, to preserve some order. - */ - sp = i2ohba->i2ohba_reqtail; - for (; sp != NULL; sp = i2ohba->i2ohba_reqtail->cmd_backw) { - if ((TGT(sp) >= start_tgt) && (TGT(sp) <= end_tgt)) { - - pkt = CMD2PKT(sp); - pkt->pkt_reason = CMD_RESET; - pkt->pkt_statistics |= STAT_DEV_RESET; - (void) i2ohba_i_req_remove(i2ohba, sp); - sp->cmd_flags |= CFLAG_FINISHED; - sp->cmd_flags = ((sp->cmd_flags & ~CFLAG_IN_TRANSPORT) - & ~CFLAG_DELAY_TIMEOUT) | CFLAG_COMPLETED; - i2ohba->i2ohba_counter--; - if (((pkt->pkt_flags & FLAG_NOINTR) == 0) && - pkt->pkt_comp) { - (*pkt->pkt_comp)(pkt); - } - - } - } - - ASSERT(I2OHBA_MUTEX_OWNED(i2ohba)); -} - - -/* - * Function name : i2ohba_scsi_abort() - * - * Return Values : 0 - abort failed - * 1 - abort succeeded - * Description : - * SCSA interface routine to abort pkt(s) in progress. - * Abort the pkt specified or NULL pkt, abort ALL pkts. - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -static int -i2ohba_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) -{ - struct i2ohba *i2ohba = ADDR2I2OHBA(ap); - struct i2ohba_cmd *sp = PKT2CMD(pkt); - uint16_t arg, tid; - int rval = 0; - - ASSERT(mutex_owned(I2OHBA_REQ_MUTEX(i2ohba)) == 0 || ddi_in_panic()); - - arg = (uint16_t)ap->a_target; - - if (i2ohba->i2ohba_tgt_id_map[arg] == NULL) - return (rval); - - tid = i2ohba->i2ohba_tgt_id_map[arg]->tid; - - /* - * hold off new requests, we need the req mutex anyway so noone - * can access the queue. - */ - I2OHBA_MUTEX_ENTER(i2ohba); - - i2ohba_i_log(NULL, CE_CONT, "?i2ohba_scsi_abort: " - "aborting pkt 0x%p", (void *)pkt); - - - if (pkt) { - if (i2ohba_i_reset_abort(i2ohba, tid, I2O_SCSI_SCB_ABORT, sp)) { - I2OHBA_MUTEX_EXIT(i2ohba); - return (0); - } - } else { - if (i2ohba_i_reset_abort(i2ohba, tid, I2O_SCSI_SCB_ABORT, 0)) { - I2OHBA_MUTEX_EXIT(i2ohba); - return (0); - } - } - - I2OHBA_MUTEX_EXIT(i2ohba); - return (1); -} - - -/* - * Function name : i2ohba_scsi_reset() - * - * Return Values : 0 - reset failed - * 1 - reset succeeded - * Description : - * SCSA interface routine to perform scsi resets on either - * a specified target or the bus (default). - * - * Context : Can be called from different kernel process threads. - * Can be called by interrupt thread. - */ -static int -i2ohba_scsi_reset(struct scsi_address *ap, int level) -{ - struct i2ohba *i2ohba = ADDR2I2OHBA(ap); - uint16_t arg, tid; - int rval = 0; - - ASSERT(mutex_owned(I2OHBA_REQ_MUTEX(i2ohba)) == 0 || ddi_in_panic()); - - arg = (uint16_t)ap->a_target; - - if (i2ohba->i2ohba_tgt_id_map[arg] == NULL) - return (rval); - - tid = i2ohba->i2ohba_tgt_id_map[arg]->tid; - - I2OHBA_MUTEX_ENTER(i2ohba); - /* - * hold off new requests, we need the req mutex. - */ - - if (level == RESET_TARGET) { - i2ohba_i_log(NULL, CE_CONT, - "?i2ohba_scsi_reset: reset target %d", ap->a_target); - - if (i2ohba_i_reset_abort(i2ohba, tid, - I2O_SCSI_DEVICE_RESET, 0)) { - return (rval); - } - } else { - i2ohba_i_log(NULL, CE_CONT, "?i2ohba_scsi_reset: reset bus"); - - tid = i2ohba->i2ohba_tid; - if (i2ohba_i_reset_abort(i2ohba, tid, I2O_HBA_BUS_RESET, 0)) { - return (rval); - } - (void) scsi_hba_reset_notify_callback( - I2OHBA_REQ_MUTEX(i2ohba), - &i2ohba->i2ohba_reset_notify_listf); - /* wait for 3 sec after a reset */ - drv_usecwait((clock_t)i2ohba->i2ohba_scsi_reset_delay * 1000); - } - I2OHBA_MUTEX_EXIT(i2ohba); - return (1); -} - -/* - * Function name: i2ohba_i_reset_abort() - * - * Return Values: 0 - success - * -1 - fail reset - * - * Description : - * Reset either the HBA Adpter or Bus Reset - * This function is called from i2ohba_i_reset_interface() - * i2ohba_scsi_abort() - * i2ohba_scsi_reset() - * - * Context : Can be called from different kernel process threads. - * Can not be called by interrupt thread because it - * waits on the reply message. - */ -static int -i2ohba_i_reset_abort(struct i2ohba *i2ohba, uint16_t tid, int action, - struct i2ohba_cmd *cmd) -{ - int rval = -1; - i2o_message_frame_t *msgptr; - i2o_scsi_scb_abort_message_t *abortmsg; - i2o_msg_handle_t msg_handle; - ddi_acc_handle_t acc_handle; - struct i2ohba_util *sp; - - if (i2o_msg_alloc(i2ohba->i2ohba_iophdl, I2O_MSG_SLEEP, NULL, - (void *)&msgptr, &msg_handle, &acc_handle) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_i_reset_abort: " - "i2o_msg_alloc failed"); - return (rval); - } - - if ((action == I2O_SCSI_SCB_ABORT) && (cmd == NULL)) - action = I2O_SCSI_DEVICE_RESET; - - abortmsg = (i2o_scsi_scb_abort_message_t *)msgptr; - /* - * construct a i2o_hba_bus_reset_message - */ - abortmsg->StdMessageFrame.VersionOffset = 0x01; - abortmsg->StdMessageFrame.MsgFlags = 0; - if (action == I2O_SCSI_SCB_ABORT) - ddi_put16(acc_handle, &abortmsg->StdMessageFrame.MessageSize, - sizeof (i2o_scsi_scb_abort_message_t) >> 2); - else - ddi_put16(acc_handle, &abortmsg->StdMessageFrame.MessageSize, - sizeof (i2o_scsi_device_reset_message_t) >> 2); - put_msg_TargetAddress(&abortmsg->StdMessageFrame, tid, acc_handle); - put_msg_InitiatorAddress(&abortmsg->StdMessageFrame, I2O_OSM_TID, - acc_handle); - put_msg_Function(&abortmsg->StdMessageFrame, action, acc_handle); - ddi_put32(acc_handle, - (uint32_t *)&abortmsg->StdMessageFrame.InitiatorContext, - (uint32_t)i2ohba_utilmsg_comp); - - /* - * allocating synchronized status buffer - */ - sp = kmem_alloc(sizeof (struct i2ohba_util), KM_SLEEP); - - ddi_put32(acc_handle, &abortmsg->TransactionContext, - (uint32_t)(uintptr_t)sp); - - if (cmd) - ddi_put32(acc_handle, &abortmsg->TransactionContextToAbort, - (uint32_t)(uintptr_t)cmd); - - /* - * initialized a mutex and cond variable to - * send message to IOP, and wait for it to signal back - */ - sp->mutex = I2OHBA_RESET_MUTEX(i2ohba); - sp->cv = I2OHBA_RESET_CV(i2ohba); - mutex_enter(sp->mutex); - sp->wakeup = UTIL_MSG_SLEEP; - sp->status = 0; - (void) i2o_msg_send(i2ohba->i2ohba_iophdl, msgptr, msg_handle); - while (!sp->wakeup) - cv_wait(sp->cv, sp->mutex); - mutex_exit(sp->mutex); - - /* - * process reply message - */ - - switch (sp->status) { - case I2O_REPLY_STATUS_SUCCESS: - rval = 0; - break; - default: - /* - * Failed the reset for now, - * we can also parse the AdapterStatus - * and retry if needed - */ - break; - } - -cleanup: - if (sp) - kmem_free(sp, sizeof (struct i2ohba_util)); - - return (rval); -} - - -/* - * Function name : i2ohba_i_reset_interface() - * - * Return Values : 0 - success - * -1 - hw failure - * - * Description : - * Master reset routine for hardware/software. Resets softc struct, - * i2ohba; and scsi bus and the scsi adapter. The works! - * This function is called from i2ohba_attach with no mutexes held or - * from i2ohba_i_fatal_error with request mutex held - * - * NOTE: it is up to the caller to flush the response queue - * - * Context : Can be called from different kernel process threads. - * i2ohba_attach() - single thread, no mutex held - * i2ohba_i_fatal_error() - * Can be called by interrupt thread. - */ -static int -i2ohba_i_reset_interface(struct i2ohba *i2ohba, int action) -{ - int i; - int rval = -1; - - /* - * Handle reset recovery; reset the bus before we reset the - * adapter chip - */ - /* - * send command Bus Reset - */ - DEBUGF(1, (CE_CONT, "Resetting i2o SCSI BUS")); - - if (action == I2OHBA_FORCE_BUS_RESET) { - if (i2ohba_i_reset_abort(i2ohba, i2ohba->i2ohba_tid, - I2O_HBA_BUS_RESET, 0)) { - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_i_reset_interface: bus reset failed"); - goto cleanup; - } - (void) scsi_hba_reset_notify_callback( - I2OHBA_REQ_MUTEX(i2ohba), - &i2ohba->i2ohba_reset_notify_listf); - drv_usecwait((clock_t)i2ohba->i2ohba_scsi_reset_delay * 1000); - } - - /* - * Handle resetting i2o host adapter. - */ - DEBUGF(1, (CE_CONT, "Resetting i2o SCSI Host Adapter")); - - /* - * Reset the i2o host adapter. - */ - if (i2ohba_i_reset_abort(i2ohba, i2ohba->i2ohba_tid, - I2O_HBA_ADAPTER_RESET, 0)) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_i_reset_interface: " - "adapter reset failed"); - goto cleanup; - } - drv_usecwait((clock_t)i2ohba->i2ohba_scsi_reset_delay * 1000); - - - /* - * set Initiator SCSI ID using utilparamset - */ - -/* - * DEBUGF(1, (CE_CONT, "Initializing SCSI HBA ID")); - * - * i = i2ohba->i2ohba_initiator_id; - * if (i2ohba_utilparamset_msg(i2ohba, 7, i2ohba->i2ohba_tid, - * I2O_HBA_SCSI_CONTROLLER_INFO_GROUP_NO, 0x4, i) != 0) { - * i2ohba_i_log(NULL, CE_WARN, "?i2ohba_i_reset_interface: " - * "resetting initiator id failed"); - * goto cleanup; - * } - * - */ - - /* - * Update sync/offset from i2ohba utilparmas to - * global per target sync area. - */ - DEBUGF(1, (CE_CONT, "Initializing i2ohba capabilities")); - - for (i = 0; i < N_I2OHBA_TARGETS_WIDE; i++) { - (void) i2ohba_i_updatesync(i2ohba, i); - } - rval = 0; - -cleanup: - if (rval) { - DEBUGF(1, (CE_WARN, "reset interface failed")); - i2ohba->i2ohba_shutdown = 1; - DEBUGF(1, (CE_WARN, "interface going offline")); - i2ohba_i_qflush(i2ohba, (uint16_t)0, - (uint16_t)N_I2OHBA_TARGETS_WIDE); - } - - return (rval); -} - - - -static void -i2ohba_i_print_state(struct i2ohba *i2ohba) -{ - char buf[128]; - int i; - - - /* - * Print out sync scsi info and suppress trailing zero - * period and offset entries. - */ - if (i2ohba->i2ohba_scsi_options & SCSI_OPTIONS_SYNC) { - (void) sprintf(buf, "period/offset:"); - for (i = 0; i < N_I2OHBA_TARGETS; i++) { - (void) sprintf(&buf[strlen(buf)], " %d/%d", - i2ohba->i2ohba_synch[i], i2ohba->i2ohba_offset[i]); - } - DEBUGF(1, (CE_CONT, buf)); - (void) sprintf(buf, "period/offset:"); - for (i = N_I2OHBA_TARGETS; i < N_I2OHBA_TARGETS_WIDE; i++) { - (void) sprintf(&buf[strlen(buf)], " %d/%d", - i2ohba->i2ohba_synch[i], i2ohba->i2ohba_offset[i]); - } - DEBUGF(1, (CE_CONT, buf)); - } -} - -/* - * Function name: i2ohba_utilparamset_msg() - * - * Return Values: 0 - success - * -1 - set prarmeter failed - * Description : common UtilParamSet function. - * However, only one param at a time. Pass in - * the Tid, GroupNumber, and the FieldIdx, and - * value, then compose the Message frame, - * then send it off through i2o_message_send(). - * - * Message Format: - * - * Building a param_set message requires: - * Buffer#1 SGL-immediate data (Request) - * 1. i2o_param_operations_list_header_t(1W) - * u16 OperationCount (1) - * u16 Reserved - * 2. i2o_param_operation_specific_template_t(2W) - * u16 Operation (FIELD_SET) - * u16 GroupNumber (group) - * u16 FieldCount 0x1 - * u16 FieldIdx (idx) - * u16 value of idx - * - * Buffer#2 SGL-Simple addressing (Reply) - * 1. i2o_param_results_list_header_t(1W) - * u16 ResultCount - * u16 Reserved - * 2. i2o_param_modify_operation_result_t(9W) - * u16 BlockSize - * u8 BlockStatus - * u8 ErrorInfoSize - * ... ErrorInformation - * - * - * Context : Can be called from i2ohba_i_reset_interface() - * Can be called from i2ohba_i_updatecap() or - * i2ohba_scsi_setcap() - */ - - -static int -i2ohba_utilparamset_msg(struct i2ohba *i2ohba, int tgt, uint16_t tid, - uint16_t group, uint16_t idx, uint16_t value) -{ - - i2o_setparam_t *msgptr; - i2o_msg_handle_t msg_handle; - ddi_acc_handle_t acc_handle; - struct i2ohba_util *sp = NULL; - uint_t count; - int rval = -1; - int bound = 0; - uint16_t allocmsgsize; - - - /* - * allocate a message frame - */ - if (i2o_msg_alloc(i2ohba->i2ohba_iophdl, I2O_MSG_SLEEP, - NULL, (void *)&msgptr, &msg_handle, &acc_handle) - != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_utilparamset_msg: " - "i2o_msg_alloc failed"); - return (rval); - } - - /* - * To get the actual allocation msg size - */ - allocmsgsize = (ddi_get16(acc_handle, &msgptr->MessageSize) << 2); - - if (allocmsgsize < sizeof (i2o_setparam_t)) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_utilparamset_msg: " - "msg size alloc is smaller than what setparam needed"); - goto fail; - } - - /* - * Construct a utilparamset message - */ - msgptr->VersionOffset = ContextSize32; - msgptr->MsgFlags = 0; - ddi_put16(acc_handle, &msgptr->MessageSize, - (sizeof (i2o_setparam_t) >> 2)); - put_msg_TargetAddress(msgptr, tid, acc_handle); - put_msg_InitiatorAddress(msgptr, I2O_OSM_TID, acc_handle); - put_msg_Function(msgptr, I2O_UTIL_PARAMS_SET, acc_handle); - ddi_put32(acc_handle, (uint32_t *)&msgptr->InitiatorContext, - (uint32_t)i2ohba_utilmsg_comp); - - /* - * allocating sychronize status buffer - */ - sp = kmem_alloc(sizeof (struct i2ohba_util), KM_SLEEP); - - ddi_put32(acc_handle, &msgptr->TransactionContext, - (uint32_t)(uintptr_t)sp); - - /* - * First message buffer's SGL and operation parameters - */ - - /* - * Buf1 SGL header: - * Immediate Data for the operation - */ - put_flags_count_Flags(&msgptr->FlagsCount1, - I2O_SGL_FLAGS_IMMEDIATE_DATA_ELEMENT - | I2O_SGL_FLAGS_END_OF_BUFFER, acc_handle); - put_flags_count_Count(&msgptr->FlagsCount1, ONE_PARAM_BLOCK, - acc_handle); - - /* - * Fill in the modify operation param for in the sgl1 payload - */ - - ddi_put16(acc_handle, &msgptr->OperationCount, 1); - ddi_put16(acc_handle, &msgptr->Operation, - I2O_PARAMS_OPERATION_FIELD_SET); - ddi_put16(acc_handle, &msgptr->GroupNumber, group); - ddi_put16(acc_handle, &msgptr->FieldCount, 0x1); - ddi_put16(acc_handle, &msgptr->FieldIdx, idx); - ddi_put16(acc_handle, &msgptr->Value, value); - - - /* - * Buf2 SGL header: - * Simple addressing - * 1. allocate the buffer for reply msg - * 2. setup the SGL header - */ - - sp->i2ohba_util_buffer = NULL; - - if (ddi_dma_alloc_handle(i2ohba->i2ohba_dip, &i2ohba_dmasgl_attr, - DDI_DMA_SLEEP, NULL, &sp->dmahandle) != - DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_utilparam_set: " - "cannot alloc dma handle"); - goto fail; - } - bound++; - if (ddi_dma_mem_alloc(sp->dmahandle, (size_t) - sizeof (i2o_param_results_list_header_t) + (size_t) - sizeof (i2o_param_modify_operation_result_t), - &dev_attr, DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, - (caddr_t *)&sp->i2ohba_util_buffer, &sp->rlen, - &sp->dma_acc_handle) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_utilparamset_msg: " - "cannot allocate param buffer"); - goto fail; - } - bound++; - put_flags_count_Flags(&msgptr->FlagsCount2, - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT | - I2O_SGL_FLAGS_END_OF_BUFFER | - I2O_SGL_FLAGS_LAST_ELEMENT, acc_handle); - - put_flags_count_Count(&msgptr->FlagsCount2, sp->rlen, acc_handle); - - - if (ddi_dma_addr_bind_handle(sp->dmahandle, NULL, - sp->i2ohba_util_buffer, (size_t) - sizeof (i2o_param_results_list_header_t) + (size_t) - sizeof (i2o_param_modify_operation_result_t) + (size_t) - sizeof (i2o_scsi_device_info_scalar_t), - DDI_DMA_RDWR|DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &sp->dmacookie, &count) != DDI_DMA_MAPPED) { - /* - * currently assume simple - * addring with one physical - * continuous address buffer. - */ - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_utilparamset_msg: " - "cannot bind buffer"); - goto fail; - } - - ddi_put32(acc_handle, &msgptr->PhysicalAddress, - (uint32_t)sp->dmacookie.dmac_address); - /* - * initialized a mutex and condvariable to - * send message to IOP, and wait for it - * to signal back - */ - sp->mutex = I2OHBA_UTILPARAM_MUTEX(i2ohba, tgt); - sp->cv = I2OHBA_UTILPARAM_CV(i2ohba, tgt); - mutex_enter(sp->mutex); - sp->wakeup = UTIL_MSG_SLEEP; - sp->status = 0; - (void) i2o_msg_send(i2ohba->i2ohba_iophdl, msgptr, msg_handle); - while (!sp->wakeup) - cv_wait(sp->cv, sp->mutex); - mutex_exit(sp->mutex); - - /* clear msg pointer */ - msgptr = NULL; - - /* - * process the data - */ - switch (sp->status) { - - i2o_setparam_reply_t *result; - uint16_t count; - uint8_t blockstatus, errinfosize; - - case I2O_REPLY_STATUS_SUCCESS: - /* - * since the reply is successful, will check - * for the opeation reulsts - */ - result = (i2o_setparam_reply_t *)sp->i2ohba_util_buffer; - count = ddi_get16(sp->dma_acc_handle, - &result->ResultCount); - if (!count) { - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_utilparamset_msg: No Results"); - break; - } - - blockstatus = ddi_get8(sp->dma_acc_handle, - &result->BlockStatus); - - errinfosize = ddi_get8(sp->dma_acc_handle, - &result->ErrorInfoSize); - - if ((blockstatus != 0) || (errinfosize != 0)) { - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_utilparamset_msg: Error " - "occured during Modify Operation"); - /* - * retrived errorinfo and possibily retry - * XXLWLXX - */ - break; - } - rval = 0; - break; - - default: - rval = -1; - break; - } - -fail: - - if (sp) { - if (bound) { - (void) ddi_dma_unbind_handle(sp->dmahandle); - if (bound > 1) - (void) ddi_dma_mem_free(&sp->dma_acc_handle); - (void) ddi_dma_free_handle(&sp->dmahandle); - } - kmem_free(sp, sizeof (struct i2ohba_util)); - } - - /* return MFA to IOP */ - if (msgptr) { - msgptr->VersionOffset = 0; - msgptr->MsgFlags = 0; - ddi_put16(acc_handle, &msgptr->MessageSize, 3); - put_msg_TargetAddress(msgptr, 0, acc_handle); - put_msg_InitiatorAddress(msgptr, 0, acc_handle); - put_msg_Function(msgptr, I2O_UTIL_NOP, acc_handle); - (void) i2o_msg_send(i2ohba->i2ohba_iophdl, msgptr, msg_handle); - } - return (rval); -} - -/* - * Function name: i2ohba_utilparamget_msg() - * - * Return Values: 0 - success - * -1 - get prarmeter failed - * - * Description : common UtilParamGet function. - * However, only one param at a time. Pass in - * the Tid, GroupNumber, and the FieldIdx, and - * value, then compose the Message frame, - * then send it off through i2o_message_send(). - * - * Message Format: - * - * building a param_get message requires - * Buffer#1 SGL-immediate data - * 1. i2o_param_operations_list_header_t(1W) - * u16 OperationCount - * u16 Reserved - * 2. i2o_param_operation_speicific_template_t(2W) - * u16 Operation (FIELD_GET) - * u16 GroupNumber - * u16 FieldCount 0xFFFF - * u16 Pad - * - * Buffer#2 SGL-Simple addressing - * Reply Message: - * 1. i2o_param_results_list_header_t(1W) - * u16 ResultCount - * u16 Reserved - * 2. i2o_param_read_operation_result_t(9W) - * u16 BlockSize - * u8 BlockStatus - * u8 ErrorInfoSize - * ... Total 8W for (ALL_PARAM_BLOCK) - * u32 Identifier - * u64 LUN - * ... - * OR Total 9 bytes (ONE_PARAM_BLOCK) - * u8 NegOffset - * u64 NegSynch - */ - -static int -i2ohba_utilparamget_msg(struct i2ohba *i2ohba, uint16_t tidx, char flag) -{ - - i2o_tid_scsi_ent_t *map = i2ohba->i2ohba_tid_scsi_map; - i2o_tid_scsi_ent_t **tgtmap = i2ohba->i2ohba_tgt_id_map; - - i2o_getsyncparam_t *msgptr; - i2o_msg_handle_t msg_handle; - ddi_acc_handle_t acc_handle; - struct i2ohba_util *sp = NULL; - uint_t count; - uint16_t allocmsgsize; - uint16_t tid; - int rval = -1; - int bound = 0; - - /* - * allocate a message frame - */ - if (i2o_msg_alloc(i2ohba->i2ohba_iophdl, I2O_MSG_SLEEP, - NULL, (void *)&msgptr, &msg_handle, &acc_handle) - != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_utilparamget_msg: " - "i2o_msg_alloc failed"); - return (rval); - } - - /* - * NOTE: - * "tidx" is either the entry number for the tid to scsi map - * or tidx is the target id, which needs tgt to id map to - * find the tid. - */ - if (flag == ALL_UTILPARAMS) { - tid = map[tidx].tid; - } else { - tid = tgtmap[tidx]->tid; - } - - /* - * To get the actual allocation msg - * size (in WORDS) - */ - allocmsgsize = (ddi_get16(acc_handle, &msgptr->MessageSize) << 2); - - - /* - * Construct a utilparamget message - */ - /* msgptr->VersionOffset = ContextSize32; */ - msgptr->VersionOffset = I2O_VERSION_11; - msgptr->MsgFlags = 0; - put_msg_TargetAddress(msgptr, tid, acc_handle); - put_msg_InitiatorAddress(msgptr, I2O_OSM_TID, acc_handle); - put_msg_Function(msgptr, I2O_UTIL_PARAMS_GET, acc_handle); - ddi_put32(acc_handle, - (uint32_t *)&msgptr->InitiatorContext.initiator_context_32bits, - (uint32_t)i2ohba_utilmsg_comp); - /* - * allocating sychroniz status buffer - */ - sp = kmem_alloc(sizeof (struct i2ohba_util), KM_SLEEP); - - ddi_put32(acc_handle, &msgptr->TransactionContext, - (uint32_t)(uintptr_t)sp); - - /* - * Buf1 SGL header: - * Immediate Data - */ - put_flags_count_Flags(&msgptr->FlagsCount1, - I2O_SGL_FLAGS_IMMEDIATE_DATA_ELEMENT | - I2O_SGL_FLAGS_END_OF_BUFFER, acc_handle); - - /* - * Fill in the read operation param for - * in the payload - */ - - ddi_put16(acc_handle, &msgptr->OperationCount, 1); - - ddi_put16(acc_handle, &msgptr->Operation, - I2O_PARAMS_OPERATION_FIELD_GET); - - ddi_put16(acc_handle, &msgptr->GroupNumber, - I2O_SCSI_DEVICE_INFO_GROUP_NO); - - /* - * End of message sending - */ - - /* - * Buf2 SGL header: - * Simple Addressing - * 1. allocating the buffer - * 2. set up the SGL header - */ - - sp->i2ohba_util_buffer = NULL; - - if (ddi_dma_alloc_handle(i2ohba->i2ohba_dip, &i2ohba_dmasgl_attr, - DDI_DMA_SLEEP, NULL, &sp->dmahandle) != - DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, "?i2ohba_utilparamget_msg: " - "cannot alloc dma handle"); - goto fail; - } - bound++; - if (flag == ALL_UTILPARAMS) { - - if (allocmsgsize < sizeof (i2o_getallparam_t)) - return (rval); - - if (ddi_dma_mem_alloc(sp->dmahandle, (size_t) - sizeof (i2o_getallparam_reply_t), &dev_attr, - DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, - (caddr_t *)&sp->i2ohba_util_buffer, &sp->rlen, - &sp->dma_acc_handle) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_utilparamget_msg: " - "cannot allocate param buffer"); - goto fail; - } - bound++; - /* StdMessageFrame */ - ddi_put16(acc_handle, &msgptr->MessageSize, - (sizeof (i2o_getallparam_t) >> 2)); - - /* i2o_sge_immediate_data_element */ - put_flags_count_Count(&msgptr->FlagsCount1, ALL_PARAM_BLOCK, - acc_handle); - - /* i2o_param_operation_all_template */ - ddi_put16(acc_handle, &msgptr->FieldCount, 0xFFFF); - - /* i2o_sge_simple_element */ - put_flags_count_Flags( - &((i2o_getallparam_t *)msgptr)->FlagsCount2, - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT | - I2O_SGL_FLAGS_END_OF_BUFFER | - I2O_SGL_FLAGS_LAST_ELEMENT, acc_handle); - - put_flags_count_Count( - &((i2o_getallparam_t *)msgptr)->FlagsCount2, - sp->rlen, acc_handle); - - if (ddi_dma_addr_bind_handle(sp->dmahandle, NULL, - sp->i2ohba_util_buffer, (size_t) - sizeof (i2o_getallparam_reply_t), - DDI_DMA_READ|DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &sp->dmacookie, &count) != DDI_SUCCESS) { - /* - * currently assume simple - * addring with one physical - * continuous address buffer. - */ - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_utilparamget_msg: " - "cannot bind buffer"); - goto fail; - } - - ddi_put32(acc_handle, - &((i2o_getallparam_t *)msgptr)->PhysicalAddress, - (uint32_t)sp->dmacookie.dmac_address); - - /* - * initialized the target param_mutex and cv. - * note: given that we don't have target id - * yet, (that is why we are here), we'll just - * use target[0]'s mutex & cv. - */ - sp->mutex = I2OHBA_UTILPARAM_MUTEX(i2ohba, 0); - sp->cv = I2OHBA_UTILPARAM_CV(i2ohba, 0); - } else { - if (allocmsgsize < sizeof (i2o_getsyncparam_t)) - return (rval); - - if (ddi_dma_mem_alloc(sp->dmahandle, (size_t) - sizeof (i2o_getsyncparam_reply_t), &dev_attr, - DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, - (void *)&sp->i2ohba_util_buffer, &sp->rlen, - &sp->dma_acc_handle) != DDI_SUCCESS) { - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_utilparamget_msg: " - "cannot allocate param buffer"); - goto fail; - } - bound++; - /* StdMessageFrame */ - ddi_put16(acc_handle, &msgptr->MessageSize, - (sizeof (i2o_getsyncparam_t) >> 2)); - - /* i2o_sge_immediate_data_element */ - put_flags_count_Count(&msgptr->FlagsCount1, ONE_PARAM_BLOCK, - acc_handle); - - /* i2o_param_operation_specific_template */ - ddi_put16(acc_handle, &msgptr->FieldCount, 0x0002); - ddi_put16(acc_handle, &msgptr->FieldIdx, 0x000A); - ddi_put16(acc_handle, &msgptr->FieldIdx, 0x0007); - - /* i2o_sge_simple_element */ - put_flags_count_Flags(&msgptr->FlagsCount2, - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT | - I2O_SGL_FLAGS_END_OF_BUFFER | - I2O_SGL_FLAGS_LAST_ELEMENT, acc_handle); - - put_flags_count_Count(&msgptr->FlagsCount2, sp->rlen, - acc_handle); - - if (ddi_dma_addr_bind_handle(sp->dmahandle, NULL, - sp->i2ohba_util_buffer, (size_t) - sizeof (i2o_getsyncparam_reply_t), - DDI_DMA_RDWR|DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &sp->dmacookie, &count) != DDI_DMA_MAPPED) { - /* - * currently assume simple - * addring with one physical - * continuous address buffer. - */ - i2ohba_i_log(NULL, CE_WARN, - "?i2ohba_utilparamget_msg: " - "cannot bind buffer"); - goto fail; - } - - ddi_put32(acc_handle, &msgptr->PhysicalAddress, - (uint32_t)sp->dmacookie.dmac_address); - - /* - * initialized the target param_mutex and cv - * tidx holds the target id number - */ - sp->mutex = I2OHBA_UTILPARAM_MUTEX(i2ohba, tidx); - sp->cv = I2OHBA_UTILPARAM_CV(i2ohba, tidx); - } - -#ifdef I2OHBA_DEBUG - DEBUGF(2, (CE_CONT, "\nmsgptr: 0x%p\n", (void *)msgptr)); - DEBUGF(2, (CE_CONT, "msgptr->VersionOffset: %x\n", - msgptr->VersionOffset)); - DEBUGF(2, (CE_CONT, "msgptr->MsgFlags: %x\n", msgptr->MsgFlags)); - DEBUGF(2, (CE_CONT, "msgptr->MessageSize: %x\n", ddi_get16(acc_handle, - &msgptr->MessageSize))); - DEBUGF(2, (CE_CONT, "msgptr->TargetAddress: %x\n", - get_msg_TargetAddress(msgptr, acc_handle))); - DEBUGF(2, (CE_CONT, "msgptr->InitiatorAddress: %x\n", - get_msg_InitiatorAddress(msgptr, acc_handle))); - DEBUGF(2, (CE_CONT, "msgptr->Function: %x\n", - get_msg_Function(msgptr, acc_handle))); - DEBUGF(2, (CE_CONT, "msgptr->InitContext: %x\n", - ddi_get32(acc_handle, - &msgptr->InitiatorContext.initiator_context_32bits))); - DEBUGF(2, (CE_CONT, "msgptr->TransContext: %x\n", - ddi_get32(acc_handle, &msgptr->TransactionContext))); - DEBUGF(2, (CE_CONT, "msgptr->OperationFlags: Resevered\n")); - DEBUGF(2, (CE_CONT, "msgptr->FlagsCount1.Flags: %x\n", - get_flags_count_Flags(&msgptr->FlagsCount1, acc_handle))); - DEBUGF(2, (CE_CONT, "msgptr->FlagsCount1.Count: %x\n", - get_flags_count_Count(&msgptr->FlagsCount1, acc_handle))); - DEBUGF(2, (CE_CONT, "msgptr->OperationCount: %x\n", - ddi_get16(acc_handle, &msgptr->OperationCount))); - DEBUGF(2, (CE_CONT, "msgptr->Operation: %x\n", - ddi_get16(acc_handle, &msgptr->Operation))); - DEBUGF(2, (CE_CONT, "msgptr->GroupNumber: %x\n", - ddi_get16(acc_handle, &msgptr->GroupNumber))); - DEBUGF(2, (CE_CONT, "msgptr->FieldCount: %x\n", - ddi_get16(acc_handle, &msgptr->FieldCount))); - DEBUGF(2, (CE_CONT, "msgptr->FlagsCount2.Flags: %x\n", - get_flags_count_Flags(&((i2o_getallparam_t *)msgptr)->FlagsCount2, - acc_handle))); - DEBUGF(2, (CE_CONT, "msgptr->FlagsCount2.Count: %x\n", - get_flags_count_Count(&((i2o_getallparam_t *)msgptr)->FlagsCount2, - acc_handle))); - DEBUGF(2, (CE_CONT, "msgptr->PhyAddr: %x\n", ddi_get32(acc_handle, - &((i2o_getallparam_t *)msgptr)->PhysicalAddress))); -#endif - /* - * initialized a mutex and condvariable to - * send message to IOP, and wait for it - * to signal back - */ - mutex_enter(sp->mutex); - sp->wakeup = UTIL_MSG_SLEEP; - sp->status = 0; - (void) i2o_msg_send(i2ohba->i2ohba_iophdl, msgptr, msg_handle); - while (!sp->wakeup) - cv_wait(sp->cv, sp->mutex); - mutex_exit(sp->mutex); - - msgptr = NULL; - - /* - * process the data - */ - switch (sp->status) { - case I2O_REPLY_STATUS_SUCCESS: - /* - * Success: - * 0) read the reply headers XXLWXX - * 1) copy buffer over to the map - * 2) unbind dma buffer - */ - - if (sp->i2ohba_util_buffer) { - uint_t tgtid; - - if (flag == ALL_UTILPARAMS) { - i2o_getallparam_reply_t *reply; - - reply = (i2o_getallparam_reply_t *) - sp->i2ohba_util_buffer; - map[tidx].scsi_info_scalar.DeviceType = - reply->DeviceType; - DEBUGF(2, (CE_CONT, "/tDeviceType:" - " 0x%x", reply->DeviceType)); - map[tidx].scsi_info_scalar.Flags = - reply->Flags; - DEBUGF(2, (CE_CONT, "/tFlags:" - " 0x%x", reply->Flags)); - map[tidx].scsi_info_scalar.Identifier = - tgtid = - ddi_get32(sp->dma_acc_handle, - &reply->Identifier); - DEBUGF(2, (CE_CONT, "/tSCSI Id: 0x%x", - tgtid)); - map[tidx].scsi_info_scalar.LunInfo[0] = 0; - map[tidx].scsi_info_scalar.QueueDepth = - ddi_get32(sp->dma_acc_handle, - &reply->QueueDepth); - DEBUGF(2, (CE_CONT, "/tQueueDepth: 0x%x", - map[tidx].scsi_info_scalar.QueueDepth)); - map[tidx].scsi_info_scalar.NegOffset = - reply->NegOffset; - DEBUGF(2, (CE_CONT, "/tQueueDepth: 0x%x", - reply->NegOffset)); - map[tidx].scsi_info_scalar.NegDataWidth = - reply->NegDataWidth; - DEBUGF(2, (CE_CONT, "/tNegDataWidth: 0x%x", - reply->NegDataWidth)); - map[tidx].scsi_info_scalar.NegSyncRate = - ddi_get64(sp->dma_acc_handle, - &reply->NegSyncRate); - DEBUGF(2, (CE_CONT, "/tNegSyncRate: 0x%x", - (uint32_t) - map[tidx].scsi_info_scalar.NegSyncRate)); - - tgtmap[tgtid] = &map[tidx]; - - } else { - i2o_getsyncparam_reply_t *reply; - - reply = (i2o_getsyncparam_reply_t *) - sp->i2ohba_util_buffer; - tgtmap[tidx]->scsi_info_scalar.NegSyncRate = - ddi_get64(sp->dma_acc_handle, - &reply->NegSyncRate); - DEBUGF(2, (CE_CONT, "/tNegSyncRate: 0x%x", - (uint32_t) - map[tidx].scsi_info_scalar.NegSyncRate)); - tgtmap[tidx]->scsi_info_scalar.NegOffset = - reply->NegOffset; - DEBUGF(2, (CE_CONT, "/tNegOffset: 0x%x", - reply->NegOffset)); - } - } - rval = 0; - break; - - case I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER: - case I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER: - default: - i2ohba_i_log(NULL, CE_WARN, "?I2O_PARAM_UTIL_GET on " - "Target %d failed", tidx); - break; - - } - -fail: - - if (sp) { - if (bound) { - (void) ddi_dma_unbind_handle(sp->dmahandle); - if (bound > 1) - (void) ddi_dma_mem_free(&sp->dma_acc_handle); - (void) ddi_dma_free_handle(&sp->dmahandle); - - } - kmem_free(sp, sizeof (struct i2ohba_util)); - } - - /* return MFA to IOP */ - if (msgptr) { - msgptr->VersionOffset = 0; - msgptr->MsgFlags = 0; - ddi_put16(acc_handle, &msgptr->MessageSize, 3); - put_msg_TargetAddress(msgptr, 0, acc_handle); - put_msg_InitiatorAddress(msgptr, 0, acc_handle); - put_msg_Function(msgptr, I2O_UTIL_NOP, acc_handle); - (void) i2o_msg_send(i2ohba->i2ohba_iophdl, msgptr, msg_handle); - } - - return (rval); -} - -/*PRINTFLIKE3*/ -static void -i2ohba_i_log(struct i2ohba *i2ohba, int level, char *fmt, ...) -{ - dev_info_t *dip; - va_list ap; - - ASSERT((mutex_owned(&i2ohba_log_mutex)) == 0 || ddi_in_panic()); - - if (i2ohba) { - dip = i2ohba->i2ohba_dip; - } else { - dip = 0; - } - - mutex_enter(&i2ohba_log_mutex); - va_start(ap, fmt); - (void) vsprintf(i2ohba_log_buf, fmt, ap); - va_end(ap); - - if (level == CE_WARN) { - scsi_log(dip, "i2o_scsi", level, "%s", i2ohba_log_buf); - } else { - scsi_log(dip, "i2o_scsi", level, "%s\n", i2ohba_log_buf); - } - mutex_exit(&i2ohba_log_mutex); -} diff --git a/usr/src/uts/common/io/i2o/i2o_scsi.conf b/usr/src/uts/common/io/i2o/i2o_scsi.conf deleted file mode 100644 index 61ac569654..0000000000 --- a/usr/src/uts/common/io/i2o/i2o_scsi.conf +++ /dev/null @@ -1,35 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# -# Copyright (c) 1998 by Sun Microsystems, Inc. -# All rights reserved. -# -#pragma ident "%Z%%M% %I% %E% SMI" - -# -# i2o_scsi.conf -# -# global definitions - -name="i2o_scsi" class="i2o"; -flow_control="dmult" queue="qsort" tape="sctp"; diff --git a/usr/src/uts/common/io/i2o/i2o_scsi_cmd.h b/usr/src/uts/common/io/i2o/i2o_scsi_cmd.h deleted file mode 100644 index abb46497a3..0000000000 --- a/usr/src/uts/common/io/i2o/i2o_scsi_cmd.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _I2O_SCSI_CMD_H -#define _I2O_SCSI_CMD_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#define PKT_PRIV_LEN 8 /* preferred pkt_private length */ -#define PKT2CMD(pkt) ((struct i2ohba_cmd *)(pkt)->pkt_ha_private) -#define CMD2PKT(sp) ((sp)->cmd_pkt) - -/* - * These are the defined flags for this structure. - */ -#define CFLAG_FINISHED 0x0001 /* command completed */ -#define CFLAG_COMPLETED 0x0002 /* completion routine called */ -#define CFLAG_IN_TRANSPORT 0x0004 /* in use by isp driver */ -#define CFLAG_DELAY_TIMEOUT 0x0008 /* delay timeout */ -#define CFLAG_TRANFLAG 0x000f /* transport part of flags */ -#define CFLAG_DMAVALID 0x0010 /* dma mapping valid */ -#define CFLAG_DMASEND 0x0020 /* data is going 'out' */ -#define CFLAG_CMDIOPB 0x0040 /* this is an 'iopb' packet */ -#define CFLAG_FREE 0x0080 /* packet is on free list */ -#define CFLAG_DMA_PARTIAL 0x0100 /* partial xfer OK */ - - -/* - * I2O command struct to keep the request and response - * - * the preferred cbd size is 12, but I2O standard defined based on - * SCSI 3. - */ - -struct i2ohba_cmd { - i2o_scsi_scb_execute_message_t *cmd_i2o_request; - struct scsi_pkt *cmd_pkt; - struct i2ohba_cmd *cmd_forw; /* forward ptr */ - struct i2ohba_cmd *cmd_backw; /* backward ptr */ - - ddi_dma_handle_t sglbuf_dmahandle; /* SGL chain buffer */ - ddi_acc_handle_t sglbuf_dmaacchandle; /* SGL chain buffer */ - ddi_dma_cookie_t sglbuf_dmacookie; - i2o_sge_chain_element_t *sglbuf; /* the buffer that holds the SGL */ - size_t sglrlen; /* the buffer that holds the SGL */ - size_t cmd_dmacount; /* totl # of bytes transfer */ - size_t cmd_xfercount; /* cur # of bytes transfer */ - ddi_dma_handle_t cmd_dmahandle; /* dma handle */ - uint_t cmd_cookie; /* next cookie */ - uint_t cmd_ncookies; /* cookies per window */ - uint_t cmd_cookiecnt; /* cookies per sub-window */ - uint_t cmd_nwin; /* number of dma windows */ - uint_t cmd_curwin; /* current dma window */ - off_t cmd_dma_offset; /* current window offset */ - ulong_t cmd_dma_len; /* current window length */ - ddi_dma_cookie_t cmd_dmacookies[I2OHBA_CMD_NSEGS]; - /* current dma cookies */ - clock_t cmd_deadline; - uint16_t cmd_flags; /* Internal state flag */ - uint8_t cmd_cdblen; - uint_t cmd_scblen; - uchar_t cmd_cdb[I2O_SCSI_CDB_LENGTH]; /* 16-SCSI3 */ - uint_t cmd_privlen; - uchar_t cmd_pkt_private[PKT_PRIV_LEN]; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* _I2O_SCSI_CMD_H */ diff --git a/usr/src/uts/common/io/i2o/i2o_scsi_util.h b/usr/src/uts/common/io/i2o/i2o_scsi_util.h deleted file mode 100644 index fc06159842..0000000000 --- a/usr/src/uts/common/io/i2o/i2o_scsi_util.h +++ /dev/null @@ -1,274 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _I2O_SCSI_UTIL_H -#define _I2O_SCSI_UTIL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Utility msg synchronization condvar - */ -#define UTIL_MSG_SLEEP 0 -#define UTIL_MSG_WAKEUP 1 - -/* - * Utility Parameter's mutex - */ -#define I2OHBA_UTILPARAM_MUTEX(i2ohba, i) (&i2ohba->util_param_mutex[i]) -#define I2OHBA_UTILPARAM_CV(i2ohba, i) (&i2ohba->util_param_cv[i]) - - -/* - * Defines for parameter size - */ -#define ONE_PARAM_BLOCK (sizeof (i2o_param_operations_list_header_t)\ - + sizeof (i2o_param_operation_specific_template_t) \ - + sizeof (uint32_t)) - -#define ALL_PARAM_BLOCK (sizeof (i2o_param_operations_list_header_t)\ - + sizeof (i2o_param_operation_all_template_t) \ - + sizeof (uint16_t)) - -/* - * Utility message's transaction context - */ -struct i2ohba_util { - int wakeup; /* value */ - int status; /* status of reply msg */ - kmutex_t *mutex; /* per request mutex */ - kcondvar_t *cv; /* per request signal */ - void *i2ohba_util_buffer; /* result operation block */ - size_t rlen; /* length of the result block */ - ddi_dma_cookie_t dmacookie; /* dma cookie for result block */ - ddi_dma_handle_t dmahandle; /* dma handle for result block */ - ddi_acc_handle_t dma_acc_handle; /* dma access handle */ -}; - -/* - * Util_Params_Get Op on all Parameters - */ - -typedef struct i2o_setparam { - - /* i2o_message_frame_t */ - uint8_t VersionOffset; - uint8_t MsgFlags; - uint16_t MessageSize; - union { - struct { - uint_t TargetAddress:12; - uint_t InitiatorAddress:12; - uint_t Function:8; - } s2; - uint32_t w2; - } u2; - i2o_initiator_context_t InitiatorContext; - - /* i2o_util_params_set_message */ - i2o_transaction_context_t TransactionContext; - uint32_t OperationFlags; - - /* SGL: i2o_sge_immediate_data_elememnt */ - i2o_flags_count_t FlagsCount1; /* 32 bits */ - /* size == ONE_PARAM_BLOCK */ - /* i2o_param_operation_list_header */ - uint16_t OperationCount; - uint16_t Reserved; - - /* i2o_param_operation_specific_template */ - uint16_t Operation; - uint16_t GroupNumber; - uint16_t FieldCount; - uint16_t FieldIdx; - uint16_t Value; /* not in struct */ - uint16_t pad; /* not in struct */ - - /* SGL: i2o_sge_simple_element */ - i2o_flags_count_t FlagsCount2; /* 32 bits */ - uint32_t PhysicalAddress; - -} i2o_setparam_t; - - -typedef struct i2o_setparam_reply { - - /* i2o_param_results_list_header_t */ - uint16_t ResultCount; - uint16_t Reserved; - - /* i2o_param_modify_operation_result */ - uint16_t BlockSize; - uint8_t BlockStatus; - uint8_t ErrorInfoSize; - /* ErrorInformation (if any) */ -} i2o_setparam_reply_t; - -#define ALL_UTILPARAMS 0x01 -#define SYNC_UTILPARAM 0x02 - -/* - * Util_Params_Get Op on all Parameters - */ - -typedef struct i2o_getallparam { - - /* i2o_message_frame_t */ - uint8_t VersionOffset; - uint8_t MsgFlags; - uint16_t MessageSize; - union { - struct { - uint_t TargetAddress:12; - uint_t InitiatorAddress:12; - uint_t Function:8; - } s2; - uint32_t w2; - } u2; - i2o_initiator_context_t InitiatorContext; - - /* i2o_util_params_get_message */ - i2o_transaction_context_t TransactionContext; - uint32_t OperationFlags; - - /* SGL: i2o_sge_immediate_data_elememnt */ - i2o_flags_count_t FlagsCount1; /* 32 bits */ - /* size == ALL_PARAM_BLOCK */ - /* i2o_param_operation_list_header */ - uint16_t OperationCount; - uint16_t Reserved; - - /* i2o_param_operation_all_template */ - uint16_t Operation; - uint16_t GroupNumber; - uint16_t FieldCount; /* (0xffff) */ - uint16_t Pad; /* not part of all temp struct */ - - /* SGL: i2o_sge_simple_element */ - i2o_flags_count_t FlagsCount2; /* 32 bits */ - uint32_t PhysicalAddress; - -} i2o_getallparam_t; - - -typedef struct i2o_getallparam_reply { - - /* i2o_param_results_list_header_t */ - uint16_t ResultCount; - uint16_t Reserved; - - /* i2o_param_read_operation_result */ - uint16_t BlockSize; - uint8_t BlockStatus; - uint8_t ErrorInfoSize; - - /* ListOfValues */ - uint8_t DeviceType; - uint8_t Flags; - uint16_t Reserved1; - uint32_t Identifier; - uint8_t LUN[8]; - uint32_t QueueDepth; - uint8_t Reserved2; - uint8_t NegOffset; - uint8_t NegDataWidth; - uint8_t Reserved3; - uint64_t NegSyncRate; - -} i2o_getallparam_reply_t; - - -/* - * Util_Params_Get Op on Synch and Offset - */ -typedef struct i2o_getsyncparam { - - /* i2o_message_frame_t */ - uint8_t VersionOffset; - uint8_t MsgFlags; - uint16_t MessageSize; - union { - struct { - uint_t TargetAddress:12; - uint_t InitiatorAddress:12; - uint_t Function:8; - } s2; - uint32_t w2; - } u2; - i2o_initiator_context_t InitiatorContext; - - /* i2o_util_params_get_message */ - i2o_transaction_context_t TransactionContext; - uint32_t OperationFlags; - - /* SGL: i2o_sge_immediate_data_elememnt */ - i2o_flags_count_t FlagsCount1; /* 32 bits */ - /* size == ONE_PARAM_BLOCK */ - /* i2o_param_operation_list_header */ - uint16_t OperationCount; - uint16_t Reserved; - - /* i2o_param_operation_specific_template */ - uint16_t Operation; - uint16_t GroupNumber; - uint16_t FieldCount; - uint16_t FieldIdx; /* field #10 */ - uint16_t FieldIdx2; /* field #7 not in struct */ - uint16_t Pad; /* not in struct */ - - /* SGL: i2o_sge_simple_element */ - i2o_flags_count_t FlagsCount2; /* 32 bits */ - uint32_t PhysicalAddress; - -} i2o_getsyncparam_t; - - -typedef struct i2o_getsyncparam_reply { - - /* i2o_param_results_list_header_t */ - uint16_t ResultCount; - uint16_t Reserved; - - /* i2o_param_read_operation_result */ - uint16_t BlockSize; - uint8_t BlockStatus; - uint8_t ErrorInfoSize; - - /* ListOfValues */ - uint64_t NegSyncRate; - uint8_t NegOffset; - -} i2o_getsyncparam_reply_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _I2O_SCSI_UTIL_H */ diff --git a/usr/src/uts/common/io/i2o/i2o_scsi_var.h b/usr/src/uts/common/io/i2o/i2o_scsi_var.h deleted file mode 100644 index 410ffe972c..0000000000 --- a/usr/src/uts/common/io/i2o/i2o_scsi_var.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998, by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _I2O_SCSI_VAR_H -#define _I2O_SCSI_VAR_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Convenient defines - */ - -/* - * Local static data - */ - -#define I2OHBA_INITIAL_SOFT_SPACE 2 /* assume 2 instances of hba */ -#define I2OHBA_CMD_NSEGS 17 -#define I2O_OSM_TID 0x01 - -#define TGT(sp) (CMD2PKT(sp)->pkt_address.a_target) -#define LUN(sp) (CMD2PKT(sp)->pkt_address.a_lun) - -/* - * Targets supported - */ -#define N_I2OHBA_LUNS 8 -#define N_I2OHBA_TARGETS 8 -#define N_I2OHBA_TARGETS_WIDE 16 - -/* - * message module defines - */ -#define ContextSize32 0x51 -#define ContextSize64 0x71 - -/* - * Default scsi-options - */ -#define I2OHBA_DEFAULT_SCSI_OPTIONS \ - SCSI_OPTIONS_PARITY | \ - SCSI_OPTIONS_DR | \ - SCSI_OPTIONS_SYNC | \ - SCSI_OPTIONS_TAG | \ - SCSI_OPTIONS_FAST | \ - SCSI_OPTIONS_WIDE - - -/* - * Mutex short hands - */ -#define I2OHBA_REQ_MUTEX(i2ohba) (&i2ohba->i2ohba_request_mutex) -#define I2OHBA_MUTEX_OWNED(i2ohba) mutex_owned(I2OHBA_REQ_MUTEX(i2ohba)) -#define I2OHBA_MUTEX_ENTER(i2ohba) mutex_enter(I2OHBA_REQ_MUTEX(i2ohba)) -#define I2OHBA_MUTEX_EXIT(i2ohba) mutex_exit(I2OHBA_REQ_MUTEX(i2ohba)) - -#define I2OHBA_RESET_MUTEX(i2ohba) (&i2ohba->reset_mutex) -#define I2OHBA_RESET_CV(i2ohba) (&i2ohba->reset_cv) - -/* - * HBA interface macros - */ -#define SDEV2TRAN(sd) ((sd)->sd_address.a_hba_tran) -#define SDEV2ADDR(sd) (&((sd)->sd_address)) -#define PKT2TRAN(pkt) ((pkt)->pkt_address.a_hba_tran) -#define ADDR2TRAN(ap) ((ap)->a_hba_tran) - -#define TRAN2I2OHBA(tran) ((struct i2ohba *)(tran)->tran_hba_private) -#define SDEV2I2OHBA(sd) (TRAN2I2OHBA(SDEV2TRAN(sd))) -#define PKT2I2OHBA(pkt) (TRAN2I2OHBA(PKT2TRAN(pkt))) -#define ADDR2I2OHBA(ap) (TRAN2I2OHBA(ADDR2TRAN(ap))) - -#define CMD2ADDR(cmd) (&CMD2PKT(cmd)->pkt_address) -#define CMD2TRAN(cmd) (CMD2PKT(cmd)->pkt_address.a_hba_tran) -#define CMD2I2OHBA(cmd) (TRAN2I2OHBA(CMD2TRAN(cmd))) - -/* - * Capability defines - */ -#define I2OHBA_CAP_DISCONNECT 0x8000 -#define I2OHBA_CAP_PARITY 0x4000 -#define I2OHBA_CAP_WIDE 0x2000 -#define I2OHBA_CAP_SYNC 0x1000 -#define I2OHBA_CAP_TAG 0x0800 -#define I2OHBA_CAP_AUTOSENSE 0x0400 -#define I2OHBA_CAP_ERRSTOP 0x0200 -#define I2OHBA_CAP_ERRSYNC 0x0100 - -/* - * delay time for polling loops - */ -#define I2OHBA_NOINTR_POLL_DELAY_TIME 1000 /* usecs */ - -/* - * value used to force bus reset in i2ohab_i_reset_interface() - */ -#define I2OHBA_FORCE_BUS_RESET 0x02 -#define PERIOD_MASK(val) ((val) & 0xff) -#define OFFSET_MASK(val) (((val) >> 8) & 0xff) - -/* - * timeout values - */ -#define I2OHBA_GRACE 10 /* Timeout margin (sec.) */ -#define I2OHBA_TIMEOUT_DELAY(secs, delay) (secs * (1000000 / delay)) - -typedef struct i2o_tid_scsi_ent { - uint16_t tid; /* associated TID */ - i2o_scsi_device_info_scalar_t scsi_info_scalar; -} i2o_tid_scsi_ent_t; - -struct i2ohba { - - /* - * Message request double link list chain - */ - struct i2ohba_cmd *i2ohba_reqhead; - struct i2ohba_cmd *i2ohba_reqtail; - - /* - * Mutex for the request or reply link list - */ - kmutex_t i2ohba_request_mutex; - /* - * Mutex for utilparam msg or reset param msg - */ - kmutex_t util_param_mutex[N_I2OHBA_TARGETS_WIDE]; - kmutex_t reset_mutex; - kcondvar_t util_param_cv[N_I2OHBA_TARGETS_WIDE]; - kcondvar_t reset_cv; - - /* - * Bus Adapter's Tid - */ - uint16_t i2ohba_tid; - - /* - * i2ohba shutdown flag - */ - uint8_t i2ohba_shutdown; - - /* - * i2ohba clear queue - */ - uint32_t i2ohba_throttle; - uint32_t i2ohba_counter; - - /* - * i2ohba timeout id - */ - timeout_id_t i2ohba_timeout_id; - - /* - * flag for updating properties in i2ohba_i_watch() - * to avoid updating in interrupt context - */ - uint16_t i2ohba_need_prop_update; - - /* - * Host adapter capabilities and offset/period values per target - * (dynamically changed by the target) - */ - uint16_t i2ohba_cap[N_I2OHBA_TARGETS_WIDE]; - uint16_t i2ohba_synch[N_I2OHBA_TARGETS_WIDE]; - uint8_t i2ohba_offset[N_I2OHBA_TARGETS_WIDE]; - uint32_t i2ohba_totsec[N_I2OHBA_TARGETS_WIDE]; - uint32_t i2ohba_secsz[N_I2OHBA_TARGETS_WIDE]; - - /* - * Transport structure for this instance of the hba - */ - scsi_hba_tran_t *i2ohba_tran; - - /* - * dev_info_t reference can be found in the transport structure - */ - dev_info_t *i2ohba_dip; - - /* - * IOP access handle (The IOP controls/associated with dip) - */ - i2o_iop_handle_t i2ohba_iophdl; - - /* - * Bus Adapter's Param - */ - i2o_hba_scsi_controller_info_scalar_t *i2ohba_scsi_controller; - - /* - * TID to SCSI/LUN target map, this hba can have upto 15 devices - */ - i2o_tid_scsi_ent_t i2ohba_tid_scsi_map[N_I2OHBA_TARGETS_WIDE]; - - i2o_tid_scsi_ent_t *i2ohba_tgt_id_map[N_I2OHBA_TARGETS_WIDE]; - - /* - * scsi options, etc from ddi_getprop() - * default value from the UtilParamGet - */ - int i2ohba_scsi_options; /* default one */ - int i2ohba_target_scsi_option[N_I2OHBA_TARGETS_WIDE]; - int i2ohba_initiator_id; - - /* - * scsi_reset_delay for i2o - */ - uint32_t i2ohba_scsi_reset_delay; - - - struct scsi_reset_notify_entry *i2ohba_reset_notify_listf; - - -}; - -#ifdef __cplusplus -} -#endif - -#endif /* _I2O_SCSI_VAR_H */ diff --git a/usr/src/uts/common/io/i2o/label.c b/usr/src/uts/common/io/i2o/label.c deleted file mode 100644 index aeaefff448..0000000000 --- a/usr/src/uts/common/io/i2o/label.c +++ /dev/null @@ -1,915 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - - -#include <sys/errno.h> -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/user.h> -#include <sys/buf.h> -#include <sys/file.h> -#include <sys/cmn_err.h> -#include <sys/uio.h> -#include <sys/kmem.h> -#include <sys/sysmacros.h> -#include <sys/stat.h> -#include <sys/scsi/scsi.h> -#include <sys/stat.h> - -#include <sys/fdio.h> - -#include <sys/errno.h> -#include <sys/open.h> -#include <sys/varargs.h> -#include <sys/fs/pc_label.h> - -#include <sys/hdio.h> -#include <sys/dkio.h> - -#include <sys/dklabel.h> - -#include <sys/vtoc.h> - - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/dditypes.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> - -#include <sys/dktp/fdisk.h> - - -#include <sys/fs/pc_label.h> - -#include <sys/i2o/i2omsg.h> -#include "i2o_bs.h" - - -static int dsklbl_chk(struct dk_label *, unsigned short *); -static void dsklbl_preplb(dsk_label_t *, dev_t, struct cb_ops *, int); -static void dsklbl_convert_lbl_to_pmap(struct dk_label *, dsk_label_t *); -static void dsklbl_savelb(struct dk_label *, dsk_label_t *); -static int dsklbl_rdvtoc(dsk_label_t *, struct buf *, struct cb_ops *); -char *partition_type(unsigned char); -void dsklbl_read_label(struct buf *, dsk_label_t *, struct cb_ops *, - struct dk_geom *, int); -void dsklbl_mprint(struct partition *); -int dsklbl_wrvtoc(dsk_label_t *, struct vtoc *, struct buf *, - struct cb_ops *); -void dsklbl_ondsklabel_to_vtoc(dsk_label_t *, struct vtoc *); -void dsklbl_vtoc_to_ondsklabel(dsk_label_t *, struct vtoc *); -void dsklbl_dgtoug(struct dk_geom *, struct dk_label *); -void dsklbl_ugtodg(struct dk_geom *, struct dk_label *); - -#ifdef DLBL_DEBUG -int label_debug = 1; - -#define DEBUGF(flag, args) \ - { if (label_debug & (flag)) cmn_err args; } -#else -#define DEBUGF(level, args) /* nothing */ -#endif - -static int -dsklbl_chk(struct dk_label *lbp, unsigned short *cksum) -{ - short *sp; - short count; - unsigned short sum; - - /* - * Check magic number of the label - */ - if (lbp->dkl_magic != DKL_MAGIC) { - DEBUGF(1, (CE_CONT, "?dsklbl_chk: magic: %x not MAGIC:" - "%x\n", lbp->dkl_magic, DKL_MAGIC)); - return (DDI_FAILURE); - } - if (lbp->dkl_vtoc.v_sanity != VTOC_SANE) { - DEBUGF(1, (CE_CONT, "?dsklbl_chk:sanity: %x not SANE:" - "%x\n", lbp->dkl_vtoc.v_sanity, VTOC_SANE)); - return (DDI_FAILURE); - } - if (lbp->dkl_vtoc.v_version != V_VERSION) { - DEBUGF(1, (CE_CONT, "?dsklbl_chk:version: %x not %x\n", - lbp->dkl_vtoc.v_version, V_VERSION)); - return (DDI_FAILURE); - } - - /* - * Check the checksum of the label - */ - sp = (short *)lbp; - sum = 0; - count = sizeof (struct dk_label) / sizeof (short); - while (count--) { - sum ^= *sp++; - } - - *cksum = sum; - if (sum) - return (DDI_FAILURE); - return (DDI_SUCCESS); -} - -/* - * We have this wonderful scenario where there exists two different kind - * of labeling scheme the x86/ppc vs. Sparc they are sufficiently different - * (read broken) that it justifies having two completely different preplb - * routines. - */ - -static void -dsklbl_preplb(dsk_label_t *lblp, dev_t dev, struct cb_ops *dev_ops, int type) -{ - long disksize; - struct dk_geom dkg; - int rval; - int s2size; - - - DEBUGF(1, (CE_CONT, "?dlbl_preplb(%x, %x)\n", lblp, dev)); - - bzero(&dkg, sizeof (struct dk_geom)); - bzero(&lblp->ondsklbl, sizeof (struct dk_label)); - - (*dev_ops->cb_ioctl)(dev, DKIOCG_PHYGEOM, - (uintptr_t)&dkg, FKIOCTL, (cred_t *)0, &rval); - - -#if defined(_SUNOS_VTOC_16) - lblp->ondsklbl.dkl_pcyl = lblp->pmap[FDISK_OFFSET+lblp->uidx].p_size / - (dkg.dkg_nhead * dkg.dkg_nsect); - - DEBUGF(1, (CE_CONT, "?dsklbl_preplb(p_size = %d, nhead = %d" - "nsect = %d)\n", - (lblp->pmap[FDISK_OFFSET+lblp->uidx].p_size), dkg.dkg_nhead, - dkg.dkg_nsect)); - -#elif defined(_SUNOS_VTOC_8) - lblp->ondsklbl.dkl_pcyl = (unsigned short)(lblp->pmap[FDISK_OFFSET+ - lblp->uidx].p_size / - (long)(dkg.dkg_nhead * dkg.dkg_nsect)); -#endif - - - - lblp->ondsklbl.dkl_acyl = 2; - lblp->ondsklbl.dkl_ncyl = lblp->ondsklbl.dkl_pcyl - - lblp->ondsklbl.dkl_acyl; - - /* or can use the size saved in ata_data (consider generic case */ - disksize = lblp->ondsklbl.dkl_ncyl * dkg.dkg_nhead * dkg.dkg_nsect; - - - lblp->ondsklbl.dkl_intrlv = 1; - lblp->ondsklbl.dkl_apc = 0; - lblp->ondsklbl.dkl_vtoc.v_nparts = V_NUMPAR; - lblp->ondsklbl.dkl_magic = DKL_MAGIC; - - lblp->ondsklbl.dkl_vtoc.v_sanity = VTOC_SANE; - lblp->ondsklbl.dkl_vtoc.v_version = V_VERSION; - - - /* - * Set up the p0 partition - */ - lblp->pmap[FPART_WHOLE+FDISK_OFFSET].p_start = 0; - lblp->pmap[FPART_WHOLE+FDISK_OFFSET].p_size = disksize; - lblp->pmap[FPART_WHOLE+FDISK_OFFSET].p_flag = V_UNMNT; - - - - /* NEEDS WORK add support for SPARC for CD */ - /* - * If CD-ROM, special-case: - * - lie about head/sect/cyl to get at every block on the disk - * - add full disk as slices 0 and 2 to the label - */ - - if (type == DKC_CDROM) { - /* - * Not heads * sectors * cyls, but the whole thing - * This applies later, to s2, as well. - */ - - - lblp->ondsklbl.dkl_nhead = 1; - lblp->ondsklbl.dkl_nsect = 1; - - /* NEEDS WORK get it from IOP probably not SD uses it too */ - lblp->ondsklbl.dkl_rpm = 200; - -#if defined(_SUNOS_VTOC_16) - - lblp->ondsklbl.dkl_vtoc.v_part[USLICE_WHOLE].p_start = 0; - lblp->ondsklbl.dkl_vtoc.v_part[USLICE_WHOLE].p_size = disksize; - lblp->ondsklbl.dkl_vtoc.v_part[USLICE_WHOLE].p_tag = V_BACKUP; - lblp->ondsklbl.dkl_vtoc.v_part[USLICE_WHOLE].p_flag = V_UNMNT; - - lblp->ondsklbl.dkl_vtoc.v_part[0].p_start = 0; - lblp->ondsklbl.dkl_vtoc.v_part[0].p_size = disksize; - lblp->ondsklbl.dkl_vtoc.v_part[0].p_tag = V_BACKUP; - lblp->ondsklbl.dkl_vtoc.v_part[0].p_flag = V_UNMNT; - - -#elif defined(_SUNOS_VTOC_8) - - /* Add full disk slice as slice 2 to the disk */ - - lblp->ondsklbl.dkl_map[USLICE_WHOLE].dkl_cylno = 0; - lblp->ondsklbl.dkl_map[USLICE_WHOLE].dkl_nblk = disksize; - - lblp->ondsklbl.dkl_map[0].dkl_cylno = 0; - lblp->ondsklbl.dkl_map[USLICE_WHOLE].dkl_nblk = disksize; - - - -#else -#error No VTOC format defined. -#endif - } else { - - /* NONE CD case */ - - - lblp->ondsklbl.dkl_nhead = dkg.dkg_nhead; - lblp->ondsklbl.dkl_nsect = dkg.dkg_nsect; - - lblp->ondsklbl.dkl_rpm = 3600; - - /* Add boot disk slice as slice 8 to the disk */ - - - /* - * There is a number of cases we have to worry about: - * - * 1) There is an fdisk partition but no Solaris partition. - * In this case the s2 slice size is zero since a valid - * Solaris partition must be present for us to decide the - * the size of the Solaris partition. - * - * 2) There is an fdisk parition and a Solaris partition. - * We got here because the Solaris partition was not labeled - * or the label has been corrupted, declare the entire Solaris - * parition as the s2 slice - * - * 3) There is no fdisk partition. - * We have to declare the entire disk as the s2 slice, - * with some room for the fdisk partition (I think) - */ - - if (lblp->fdiskpresent) { - if (lblp->uidx == 0) { /* FDISK - Solaris (1 above) */ - s2size = 0; - } else { /* FDISK + Solaris (2 above) */ - s2size = lblp->pmap[lblp->uidx+FDISK_OFFSET].p_size; - } - } else { /* No FDISK (3 above) */ - s2size = disksize; - } -#if defined(_SUNOS_VTOC_16) - /* - * If this is x86/PowerPC format label - */ - - lblp->ondsklbl.dkl_vtoc.v_sectorsz = NBPSCTR; - - /* Add full disk slice as slice 2 to the disk */ - - lblp->ondsklbl.dkl_vtoc.v_part[USLICE_WHOLE].p_start = 0; - lblp->ondsklbl.dkl_vtoc.v_part[USLICE_WHOLE].p_size = s2size; - lblp->ondsklbl.dkl_vtoc.v_part[USLICE_WHOLE].p_tag = V_BACKUP; - lblp->ondsklbl.dkl_vtoc.v_part[USLICE_WHOLE].p_flag = V_UNMNT; - - lblp->ondsklbl.dkl_vtoc.v_part[8].p_start = 0; - lblp->ondsklbl.dkl_vtoc.v_part[8].p_size = - dkg.dkg_nhead * dkg.dkg_nsect; - lblp->ondsklbl.dkl_vtoc.v_part[8].p_tag = V_BOOT; - lblp->ondsklbl.dkl_vtoc.v_part[8].p_flag = V_UNMNT; - - /* For now this is not a requirenment */ - /* Add Alternates disk slice as slice 9 to the disk */ - - lblp->ondsklbl.dkl_vtoc.v_part[9].p_start = - dkg.dkg_nhead * dkg.dkg_nsect; - lblp->ondsklbl.dkl_vtoc.v_part[9].p_size = - 2 * dkg.dkg_nhead * dkg.dkg_nsect; - lblp->ondsklbl.dkl_vtoc.v_part[9].p_tag = V_ALTSCTR; - lblp->ondsklbl.dkl_vtoc.v_part[9].p_flag = 0; - - (void) sprintf(lblp->ondsklbl.dkl_vtoc.v_asciilabel, - "DEFAULT cyl %d alt %d hd %d sec %d", - lblp->ondsklbl.dkl_ncyl, - lblp->ondsklbl.dkl_acyl, - lblp->ondsklbl.dkl_nhead, - lblp->ondsklbl.dkl_nsect); -#elif defined(_SUNOS_VTOC_8) - - /* Add full disk slice as slice 2 to the disk */ - - lblp->ondsklbl.dkl_map[USLICE_WHOLE].dkl_cylno = 0; - lblp->ondsklbl.dkl_map[USLICE_WHOLE].dkl_nblk = s2size; - - (void) sprintf(lblp->ondsklbl.dkl_asciilabel, - "DEFAULT cyl %d alt %d hd %d sec %d", - lblp->ondsklbl.dkl_ncyl, - lblp->ondsklbl.dkl_acyl, - lblp->ondsklbl.dkl_nhead, - lblp->ondsklbl.dkl_nsect); -#else -#error No VTOC format defined. -#endif - - - - } - - (void) dsklbl_chk(&lblp->ondsklbl, &(lblp->ondsklbl.dkl_cksum)); - /* - * now that an on disk label is manufactured, convert so - * that we start using right away - * is this the right thing to do, we also need a mutex - * to protext it. - * - * dsklbl_convert_lbl_to_pmap(&lblp->ondsklbl, lblp); - * - */ - -} - -static void -dsklbl_convert_lbl_to_pmap(struct dk_label *lbp, dsk_label_t *lblp) -{ - int i; -#if defined(_SUNOS_VTOC_16) - bcopy((caddr_t)&lbp->dkl_vtoc.v_part, - (caddr_t)lblp->pmap, sizeof (lbp->dkl_vtoc.v_part)); -#elif defined(_SUNOS_VTOC_8) - for (i = 0; i < NDKMAP; i++) { - lblp->pmap[i].p_tag = lbp->dkl_vtoc.v_part[i].p_tag; - lblp->pmap[i].p_flag = lbp->dkl_vtoc.v_part[i].p_flag; - lblp->pmap[i].p_start = lbp->dkl_map[i].dkl_cylno * - lblp->ondsklbl.dkl_nhead * lblp->ondsklbl.dkl_nsect; - lblp->pmap[i].p_size = lbp->dkl_map[i].dkl_nblk; - } -#else -#error No VTOC format defined. -#endif - for (i = 0; i < NDKMAP; i++) { - lblp->pmap[i].p_start += - lblp->pmap[lblp->uidx+FDISK_OFFSET].p_start; - } -} - -static void -dsklbl_savelb(struct dk_label *lbp, dsk_label_t *lblp) -{ - /* - * save the disk label in memory - */ - - bcopy((caddr_t)lbp, (caddr_t)&lblp->ondsklbl, sizeof (*lbp)); - - dsklbl_convert_lbl_to_pmap(lbp, lblp); -#ifdef DLBL_DEBUG - dsklbl_mprint(lblp->pmap); -#endif -} - -static int -dsklbl_rdvtoc(dsk_label_t *lblp, struct buf *bp, struct cb_ops *dev_ops) -{ - struct dk_label *lbp; - unsigned short sum; - - /* - * read the label - */ - DEBUGF(1, (CE_CONT, "?dsklbl_rdvtoc(%x, %x)\n", lblp, bp)); - bp->b_bcount = 1 * DEV_BSIZE; - bp->b_flags = B_READ; - bp->b_blkno = lblp->pmap[FDISK_OFFSET+lblp->uidx].p_start+VTOC_OFFSET; - - (*dev_ops->cb_strategy)(bp); - (void) biowait(bp); - - - lbp = (struct dk_label *)bp->b_un.b_addr; - - /* - * check label - */ - if ((!lbp) || (dsklbl_chk(lbp, &sum) == DDI_FAILURE)) { - DEBUGF(1, (CE_CONT, - "?label does not have a valid checksum\n")); - return (DDI_FAILURE); - } - /* - * record label information - */ - dsklbl_savelb(lbp, lblp); - lblp->vtocread = 1; - - return (DDI_SUCCESS); -} - - -struct { - unsigned char id; - char *name; -} partitionname[] = { - { 0x01, "DOS 12-bit FAT" }, - { 0x02, "XENIX /" }, - { 0x03, "XENIX /usr" }, - { 0x04, "DOS 16-bit FAT <32M" }, - { 0x05, "DOS Extended Partition" }, - { 0x06, "DOS 16-bit FAT >=32M" }, - { 0x07, "OS/2 IFS (e.g., HPFS) or NTFS or QNX2.x or Advanced UNIX" }, - { 0x08, "AIX boot or SplitDrive" }, - { 0x09, "AIX data or Coherent" }, - { 0x0a, "OS/2 Boot Manager" }, - { 0x0e, "DOS 16-bit FAT, CHS-mapped" }, - { 0x0f, "Extended partition, CHS-mapped" }, - { 0x10, "OPUS" }, - { 0x11, "OS/2 BM: Hidden DOS 12-bit FAT" }, - { 0x12, "Compaq config partition" }, - { 0x14, "OS/2 BM: Hidden DOS 16-bit FAT <32M" }, - { 0x16, "OS/2 BM: Hidden DOS 16-bit FAT >=32M" }, - { 0x17, "OS/2 BM: Hidden IFS (e.g., HPFS)" }, - { 0x18, "AST Windows swapfile" }, - { 0x24, "NEC DOS" }, - { 0x3c, "PartitionMagic recovery partition" }, - { 0x40, "Venix 80286" }, - { 0x41, "Linux/MINIX (sharing disk with DRDOS)" }, - { 0x42, "Linux swap (sharing disk with DRDOS) or SFS" }, - { 0x43, "Linux native (sharing disk with DRDOS)" }, - { 0x50, "OnTrack DM RO" }, - { 0x51, "OnTrack DM RW (DM6 Aux1) or Novell" }, - { 0x52, "CP/M or Microport SysV/AT" }, - { 0x53, "DM6 Aux3" }, - { 0x54, "DM6" }, - { 0x55, "EZ-Drive" }, - { 0x56, "Golden Bow VFeature Partitioned Volume." }, - { 0x5C, "Priam EDisk" }, - { 0x61, "SpeedStor" }, - { 0x63, "Unix System V (SCO, ISC UNIX, UnixWare, ...)" }, - { 0x64, "Novell Netware 2.xx" }, - { 0x65, "Novell Netware 3.xx or 4.xx" }, - { 0x70, "DiskSecure Multi-Boot" }, - { 0x75, "PC/IX" }, - { 0x77, "QNX4.x" }, - { 0x78, "QNX4.x 2nd part" }, - { 0x79, "QNX4.x 3rd part" }, - { 0x80, "MINIX until 1.4a" }, - { 0x81, "MINIX since 1.4b, early Linux, Mitac dmgr" }, - { 0x82, "Solaris" }, - { 0x83, "Linux native" }, - { 0x84, "OS/2 hidden C: drive" }, - { 0x85, "Linux extended partition" }, - { 0x86, "NTFS volume set??" }, - { 0x87, "NTFS volume set??" }, - { 0x93, "Amoeba" }, - { 0x94, "Amoeba bad track table" }, - { 0xa0, "IBM Thinkpad hibernation partition" }, - { 0xa5, "BSD/386, 386BSD, NetBSD, FreeBSD" }, - { 0xa7, "NEXTSTEP" }, - { 0xb7, "BSDI fs" }, - { 0xb8, "BSDI swap" }, - { 0xc1, "DRDOS/sec (FAT-12)" }, - { 0xc4, "DRDOS/sec (FAT-16, < 32M)" }, - { 0xc6, "DRDOS/sec (FAT-16, >= 32M)" }, - { 0xc7, "Syrinx" }, - { 0xdb, "Concurrent CP/M or Concurrent DOS or CTOS" }, - { 0xe1, "DOS access or SpeedStor 12-bit FAT extended partition" }, - { 0xe3, "DOS R/O or SpeedStor" }, - { 0xe4, "SpeedStor 16-bit FAT extended partition < 1024 cyl." }, - { 0xf1, "SpeedStor" }, - { 0xf2, "DOS 3.3+ secondary" }, - { 0xf4, "SpeedStor large partition" }, - { 0xfe, "SpeedStor >1024 cyl. or LANstep" }, - { 0xff, "Xenix Bad Block Table" } -}; - -char * -partition_type(unsigned char systid) -{ - int i; - - for (i = 0; i < sizeof (partitionname)/sizeof (partitionname[0]); i++) - if (partitionname[i].id == systid) - return (partitionname[i].name); - - return ("Unknown"); -} - -int -parse_fdisk_lbl(struct buf *bp, dsk_label_t *lblp, struct cb_ops *dev_ops, - struct dk_geom *dkg, int type) -{ - struct mboot *mbp; - struct ipart *fdp; - int i, uidx; - struct ipart fdisk[FD_NUMPART]; - - /* - * The whole disk is represented here (this is the p0 partition.) - */ - lblp->pmap[FPART_WHOLE+FDISK_OFFSET].p_start = 0; - lblp->pmap[FPART_WHOLE+FDISK_OFFSET].p_size = - dkg->dkg_ncyl * dkg->dkg_nhead * dkg->dkg_nsect; - lblp->pmap[FPART_WHOLE+FDISK_OFFSET].p_flag = V_UNMNT; - - mbp = (struct mboot *)bp->b_un.b_addr; - - if (!mbp || ltohs(mbp->signature) != MBB_MAGIC) { - - DEBUGF(1, (CE_CONT, - "?lbl 0x%x does not have an fdisk table.\n", - bp->b_edev)); -#ifdef DLBL_DEBUG - if (mbp) - DEBUGF(1, (CE_CONT, "?lbl " - "expteced magic: 0x%x got 0x%x\n", - MBB_MAGIC, ltohs(mbp->signature))); -#endif - DEBUGF(1, (CE_CONT, - "parse_label: b_edev %x " - "b_dev = %x\n", - bp->b_edev, bp->b_dev)); - - lblp->fdiskpresent = 0; - lblp->uidx = 0; - if (dsklbl_rdvtoc(lblp, bp, dev_ops) == DDI_FAILURE) { - bp->b_dev = cmpdev(bp->b_edev); - dsklbl_preplb(lblp, bp->b_edev, dev_ops, type); - } - return (DDI_SUCCESS); - } - /* - * The fdisk table does not begin on a 4-byte boundary within - * the master boot record; so, we need to recopy its contents to - * another data structure to avoid an alignment exception. - * This is not necessary for x86, but it avoids ifdefs - */ - fdp = fdisk; - bcopy((caddr_t)&(mbp->parts[0]), (caddr_t)fdp, sizeof (fdisk)); - - DEBUGF(1, (CE_CONT, - "?---------------------- Partition Table -----------------\n")); - DEBUGF(1, (CE_CONT, "?index relsect numsect type\n")); - DEBUGF(1, (CE_CONT, - "?------- ------- ------- -----------------------------\n")); - - for (uidx = 0, i = 1; i <= FD_NUMPART; i++, fdp++) { - if (!fdp->numsect) { - lblp->pmap[i+FDISK_OFFSET].p_flag = V_INVALID; - continue; - } - lblp->pmap[i+FDISK_OFFSET].p_start = ltohi(fdp->relsect); - lblp->pmap[i+FDISK_OFFSET].p_size = ltohi(fdp->numsect); - DEBUGF(1, (CE_CONT, "?%7d %7d %7d %4x (%s)\n", i, - ltohi(fdp->relsect), - ltohi(fdp->numsect), - fdp->systid, partition_type(fdp->systid))); - if (fdp->systid == SUNIXOS || fdp->systid == SUNIXOS2) { - if (uidx == 0) - uidx = i; - else if (fdp->bootid == ACTIVE) - uidx = i; - } - } - - lblp->fdiskpresent = 1; - lblp->uidx = uidx; - if (dsklbl_rdvtoc(lblp, bp, dev_ops) == DDI_FAILURE) { - bp->b_dev = cmpdev(bp->b_edev); - dsklbl_preplb(lblp, bp->b_edev, dev_ops, type); - - } - return (DDI_SUCCESS); -} - -void -dsklbl_read_label(struct buf *bp, dsk_label_t *lblp, struct cb_ops *dev_ops, - struct dk_geom *dkg, int type) -{ - /* - * read the label - */ - - bp->b_bcount = 1 * DEV_BSIZE; - bp->b_flags = B_READ; - bp->b_blkno = 0; - (*dev_ops->cb_strategy)(bp); - (void) biowait(bp); - (void) parse_fdisk_lbl(bp, lblp, dev_ops, dkg, type); -} - -#ifdef DLBL_DEBUG -void -dsklbl_mprint(struct partition *pp) -{ - int i; - - cmn_err(CE_CONT, "?----- UNIX slices -----\n"); - cmn_err(CE_CONT, "?slice start size\n"); - cmn_err(CE_CONT, "?----- ------ --------\n"); - for (i = 0; i < NDKMAP; i++, pp++) { - if (pp->p_size) { - cmn_err(CE_CONT, "?%5d %6x %x\n", i, pp->p_start, - pp->p_size); - } - } -} -#endif - - -int -dsklbl_wrvtoc(dsk_label_t *lblp, struct vtoc *vtocp, struct buf *bp, - struct cb_ops *dev_ops) -{ - register struct dk_label *lbp, *dp; - int status; - int backup_block; - int count; - - /* - * Data is originated from vtoc. One copy of the data is stored in - * lblp->ondsklbl. This is what we think of as the copy of the lable - * on this held in memory. The other copy (to the lbp) is to be - * written out to the disk. - */ - dp = &lblp->ondsklbl; - - bp->b_bcount = 1 * DEV_BSIZE; - bp->b_flags = B_WRITE | B_BUSY; - - lbp = (struct dk_label *)bp->b_un.b_addr; - - dsklbl_vtoc_to_ondsklabel(lblp, vtocp); - *lbp = lblp->ondsklbl; - - /* - * check label - */ - if (lblp->uidx) - bp->b_blkno = lblp->pmap[FDISK_OFFSET+lblp->uidx].p_start; - else - bp->b_blkno = 0; - bp->b_blkno += VTOC_OFFSET; - - - (*dev_ops->cb_strategy)(bp); - status = biowait(bp); - - if (status != 0 || dp->dkl_acyl == 0) - return (status); - - /* - * DO backup copies of vtoc - */ - - backup_block = ((dp->dkl_ncyl + dp->dkl_acyl - 1) * - (dp->dkl_nhead * dp->dkl_nsect)) + - ((dp->dkl_nhead - 1) * dp->dkl_nsect) + 1; - - bcopy((caddr_t)&(lblp->ondsklbl), (caddr_t)lbp, sizeof (*lbp)); - for (count = 1; count < 6; count++) { - - bp->b_blkno = - lblp->pmap[FDISK_OFFSET+lblp->uidx].p_start+backup_block; - bp->b_flags = B_WRITE | B_BUSY; - - (*dev_ops->cb_strategy)(bp); - (void) biowait(bp); - - backup_block += 2; - } - return (0); -} - - - -void -dsklbl_ondsklabel_to_vtoc(dsk_label_t *lblp, struct vtoc *vtocp) -{ -#if defined(_SUNOS_VTOC_16) - bcopy((caddr_t)&lblp->ondsklbl.dkl_vtoc, (caddr_t)vtocp, - sizeof (*vtocp)); -#elif defined(_SUNOS_VTOC_8) - int i; - long nblks; - struct dk_map2 *lpart; - struct dk_map *lmap; - struct partition *vpart; - - - /* - * Data is originated from vtoc. One copy of the data is stored in - * lblp->ondsklbl. This is what we think of as the copy of the label - * on the disk held in memory. The other copy (to the lbp) is to be - * written out to the disk. - */ - - /* - * Put appropriate vtoc structure fields into the disk label - * - */ - bcopy((caddr_t)(lblp->ondsklbl.dkl_vtoc.v_bootinfo), - (caddr_t)vtocp->v_bootinfo, sizeof (vtocp->v_bootinfo)); - - /* For now may want to add the sectorsz field to the generic structur */ - vtocp->v_sectorsz = NBPSCTR; /* sector size in bytes */ - - vtocp->v_sanity = lblp->ondsklbl.dkl_vtoc.v_sanity; - vtocp->v_version = lblp->ondsklbl.dkl_vtoc.v_version; - - bcopy((caddr_t)lblp->ondsklbl.dkl_vtoc.v_volume, - (caddr_t)vtocp->v_volume, LEN_DKL_VVOL); - - vtocp->v_nparts = lblp->ondsklbl.dkl_vtoc.v_nparts; - - bcopy((caddr_t)lblp->ondsklbl.dkl_vtoc.v_reserved, - (caddr_t)vtocp->v_reserved, sizeof (vtocp->v_reserved)); - - /* - * Note the conversion from starting sector number - * to starting cylinder number. - */ - nblks = lblp->ondsklbl.dkl_nsect * lblp->ondsklbl.dkl_nhead; - - lmap = lblp->ondsklbl.dkl_map; - lpart = (struct dk_map2 *)lblp->ondsklbl.dkl_vtoc.v_part; - vpart = vtocp->v_part; - - for (i = 0; i < (int)vtocp->v_nparts; i++) { - vpart->p_tag = lpart->p_tag; - vpart->p_flag = lpart->p_flag; - vpart->p_start = lmap->dkl_cylno * nblks; - vpart->p_size = lmap->dkl_nblk; - - lmap++; - lpart++; - vpart++; - } - - bcopy((caddr_t)lblp->ondsklbl.dkl_vtoc.v_timestamp, - (caddr_t)vtocp->timestamp, sizeof (vtocp->timestamp)); - - bcopy((caddr_t)lblp->ondsklbl.dkl_asciilabel, - (caddr_t)vtocp->v_asciilabel, - LEN_DKL_ASCII); - -#else -#error No VTOC format defined. -#endif -} - -void -dsklbl_vtoc_to_ondsklabel(dsk_label_t *lblp, struct vtoc *vtocp) -{ -#if defined(_SUNOS_VTOC_16) - bcopy((caddr_t)vtocp, (caddr_t)&(lblp->ondsklbl.dkl_vtoc), - sizeof (*vtocp)); -#elif defined(_SUNOS_VTOC_8) - /* - * Put appropriate vtoc structure fields into the disk label - * - */ - int i; - long nblks; - struct dk_map2 *lpart; - struct dk_map *lmap; - struct partition *vpart; - register struct dk_label *dp; - - /* - * Data is originated from vtoc. One copy of the data is stored in - * lblp->ondsklbl. This is what we think of as the copy of the label - * on this disk held in memory. The other copy (to the lbp) is to be - * written out to the disk. - */ - dp = &lblp->ondsklbl; - - - bcopy((caddr_t)vtocp->v_bootinfo, - (caddr_t)(lblp->ondsklbl.dkl_vtoc.v_bootinfo), - sizeof (vtocp->v_bootinfo)); - - lblp->ondsklbl.dkl_vtoc.v_sanity = vtocp->v_sanity; - lblp->ondsklbl.dkl_vtoc.v_version = vtocp->v_version; - - bcopy((caddr_t)vtocp->v_volume, - (caddr_t)lblp->ondsklbl.dkl_vtoc.v_volume, - LEN_DKL_VVOL); - - lblp->ondsklbl.dkl_vtoc.v_nparts = vtocp->v_nparts; - - bcopy((caddr_t)vtocp->v_reserved, - (caddr_t)lblp->ondsklbl.dkl_vtoc.v_reserved, - sizeof (vtocp->v_reserved)); - - /* - * Note the conversion from starting sector number - * to starting cylinder number. - */ - nblks = dp->dkl_nsect * dp->dkl_nhead; - lmap = lblp->ondsklbl.dkl_map; - lpart = (struct dk_map2 *)lblp->ondsklbl.dkl_vtoc.v_part; - vpart = vtocp->v_part; - - for (i = 0; i < (int)vtocp->v_nparts; i++) { - lpart->p_tag = vpart->p_tag; - lpart->p_flag = vpart->p_flag; - lmap->dkl_cylno = vpart->p_start / nblks; - lmap->dkl_nblk = vpart->p_size; - - lmap++; - lpart++; - vpart++; - } - - bcopy((caddr_t)vtocp->timestamp, - (caddr_t)lblp->ondsklbl.dkl_vtoc.v_timestamp, - sizeof (vtocp->timestamp)); - - bcopy((caddr_t)vtocp->v_asciilabel, - (caddr_t)lblp->ondsklbl.dkl_asciilabel, - LEN_DKL_ASCII); - -#else -#error No VTOC format defined. -#endif - - lblp->ondsklbl.dkl_cksum = 0; - (void) dsklbl_chk(&lblp->ondsklbl, &(lblp->ondsklbl.dkl_cksum)); -} - -void -dsklbl_dgtoug(struct dk_geom *up, struct dk_label *dp) -{ - DEBUGF(1, (CE_CONT, "?dsklbl_dgtoug: pcyl = %d ncyl = %d acyl = %d\n", - dp->dkl_pcyl, dp->dkl_ncyl, dp->dkl_acyl)); - - up->dkg_pcyl = dp->dkl_pcyl; - up->dkg_ncyl = dp->dkl_ncyl; - up->dkg_acyl = dp->dkl_acyl; -#if !defined(__sparc) - up->dkg_bcyl = dp->dkl_bcyl; -#endif - up->dkg_nhead = dp->dkl_nhead; - up->dkg_nsect = dp->dkl_nsect; - up->dkg_intrlv = dp->dkl_intrlv; - up->dkg_apc = dp->dkl_apc; - up->dkg_rpm = dp->dkl_rpm; - up->dkg_write_reinstruct = dp->dkl_write_reinstruct; - up->dkg_read_reinstruct = dp->dkl_read_reinstruct; -} - - - - -void -dsklbl_ugtodg(struct dk_geom *up, struct dk_label *dp) -{ - dp->dkl_pcyl = up->dkg_pcyl; - dp->dkl_ncyl = up->dkg_ncyl; - dp->dkl_acyl = up->dkg_acyl; -#if !defined(__sparc) - dp->dkl_bcyl = up->dkg_bcyl; -#endif - dp->dkl_nhead = up->dkg_nhead; - dp->dkl_nsect = up->dkg_nsect; - dp->dkl_intrlv = up->dkg_intrlv; - dp->dkl_apc = up->dkg_apc; - dp->dkl_rpm = up->dkg_rpm; - dp->dkl_write_reinstruct = up->dkg_write_reinstruct; - dp->dkl_read_reinstruct = up->dkg_read_reinstruct; -} diff --git a/usr/src/uts/common/io/i2o/pci_to_i2o.c b/usr/src/uts/common/io/i2o/pci_to_i2o.c deleted file mode 100644 index 0dc8105d0e..0000000000 --- a/usr/src/uts/common/io/i2o/pci_to_i2o.c +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * PCI-to-I2O bus nexus driver. - * - * The current implementation complies with the I2O Specification - * Version 1.5. So, it assumes only 32bit virtual addresses and - * 32bit context fields in I2O messages. - */ - -#include <sys/types.h> -#include <sys/cmn_err.h> -#include <sys/conf.h> -#include <sys/debug.h> -#include <sys/errno.h> -#include <sys/modctl.h> -#include <sys/ddidmareq.h> -#include <sys/ddi_impldefs.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/sunndi.h> -#include <sys/pci.h> -#include <sys/avintr.h> -#include <sys/bustypes.h> -#include <sys/kmem.h> -#include <sys/archsystm.h> -#include <sys/i2o/i2oexec.h> -#include "i2o_impl.h" - -char _depends_on[] = "misc/i2o_msg"; - -/* - * function prototypes for bus ops routines: - */ -static int -i2o_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr, - int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep); - -static int -i2o_bus_ctl(dev_info_t *dip, dev_info_t *rdip, - ddi_ctl_enum_t opt, void *a, void *v); - -static int -i2o_intr_op(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t op, - ddi_intr_handle_impl_t *hdlp, void *result); - -struct bus_ops i2o_bus_ops = { - BUSO_REV, - nullbusmap, - NULL, - NULL, - NULL, - i_ddi_map_fault, - ddi_no_dma_map, /* 2.4 DDI only - not supported */ - i2o_dma_allochdl, - ddi_dma_freehdl, - ddi_dma_bindhdl, - ddi_dma_unbindhdl, - ddi_dma_flush, - ddi_dma_win, - ddi_dma_mctl, - i2o_bus_ctl, - ddi_bus_prop_op, - NULL, /* (* bus_get_eventcookie)() */ - NULL, /* (* bus_add_eventcall)() */ - NULL, /* (* bus_remove_eventcall)() */ - NULL, /* (* bus_post_event)() */ - NULL, /* interrupt control */ - 0, /* bus_config */ - 0, /* bus_unconfig */ - 0, /* bus_fm_init */ - 0, /* bus_fm_fini */ - 0, /* bus_fm_access_enter */ - 0, /* bus_fm_access_exit */ - 0, /* bus_power */ - i2o_intr_op /* bus_intr_op */ -}; - - -/* - * Function prototypes for dev_ops entry points. - */ - -static int i2o_probe(dev_info_t *); -static int i2o_attach(dev_info_t *, ddi_attach_cmd_t); -static int i2o_detach(dev_info_t *, ddi_detach_cmd_t); - -struct dev_ops i2o_dev_ops = { - DEVO_REV, /* devo_rev */ - 0, /* refcnt */ - ddi_no_info, /* info */ - nulldev, /* identify */ - i2o_probe, /* probe */ - i2o_attach, /* attach */ - i2o_detach, /* detach */ - nodev, /* reset */ - (struct cb_ops *)0, /* driver operations */ - &i2o_bus_ops /* bus operations */ -}; - -/* - * Per IOP instance data maintained by the i2o nexus driver. - */ - -typedef struct iop_nexus_instance { - dev_info_t *dip; /* devinfo pointer */ - caddr_t iop_base_addr; /* base address of shared memory */ - int iop_state; /* state of IOP */ - off_t shared_memsize; /* size of shared memory */ - int iop_intr_pri; /* interrupt priority */ - ddi_acc_handle_t acc_handle; /* DDI access handle for shared mem */ - i2o_iop_handle_t i2o_iop_handle; /* IOP handle from the i2o_msg module */ - ddi_iblock_cookie_t iblock_cookie; - ddi_idevice_cookie_t idevice_cookie; - i2o_msg_trans_t i2o_msg_trans; -#ifdef I2O_DEBUG - uint_t intr_count; /* IOP interrupt counter */ -#endif -} iop_nexus_instance_t; - - -/* Function prototypes for local functions */ - -static uint_t i2o_intr(caddr_t); -static uint_t i2o_alloc_msg(i2o_nexus_handle_t handle); -static int i2o_send_msg(i2o_nexus_handle_t handle, uint_t mfa); -static uint_t i2o_recv_msg(i2o_nexus_handle_t handle); -static void i2o_disable_intr(i2o_nexus_handle_t handle); -static void i2o_enable_intr(i2o_nexus_handle_t handle); -static void i2o_free_msg(i2o_nexus_handle_t handle, uint_t mfa); -static void i2o_create_devinfo(iop_nexus_instance_t *iop); -#ifdef I2O_DEBUG -static void dump_exec_params_0001(iop_nexus_instance_t *iop); -void i2o_msg_reply(void *m, ddi_acc_handle_t acc_hdl); -#endif - -/* - * DMA attribute structure for I2O Spec version 1.5. - */ -static ddi_dma_attr_t i2o_dma_attr = { - DMA_ATTR_VERSION, /* version number */ - (uint64_t)0, /* low DMA address range */ - (uint64_t)0xFFFFFFFF, /* high DMA address range */ - (uint64_t)0x00FFFFFF, /* DMA counter register */ - 1, /* DMA address alignment */ - 1, /* DMA burstsizes */ - 1, /* min effective DMA size */ - (uint64_t)0xFFFFFFFF, /* max DMA xfer size */ - (uint64_t)0xFFFFFFFF, /* segment boundary */ - 0xFFFF, /* s/g length */ - 1, /* granularity of device */ - 0 /* Bus specific DMA flags */ -}; - - -/* local definitions for iop_state values */ -#define IOP_INIT 0 /* IOP is being initialized */ -#define IOP_ONLINE 1 /* IOP initialization is complete */ - - -/* Default interrupt priority for IOP interrupt */ -#define IOP_INTR_PRI_DEFAULT 5 - - -#ifdef I2O_DEBUG -int i2o_nexus_debug = 0; -#define DEBUGF(level, args) \ - { if (i2o_nexus_debug >= (level)) cmn_err args; } -#else -#define DEBUGF(level, args) /* nothing */ -#endif - - -/* - * Module linkage information for the kernel. - */ -static struct modldrv modldrv = { - &mod_driverops, - "Nexus for I2O Spec v1.5, driver %I%", - &i2o_dev_ops, -}; - - -/* - * Device attribute structure for I2O version 1.5. - * - * I2O data structures (whether it is in IOP's memory or host memory) - * are in Little Endian format. - */ -static ddi_device_acc_attr_t i2o_dev_acc_attr = { - DDI_DEVICE_ATTR_V0, - DDI_STRUCTURE_LE_ACC, /* devacc_attr_endian_flags for LE access */ - DDI_STRICTORDER_ACC /* devacc_attr_dataorder */ -}; - - -static struct modlinkage modlinkage = { - MODREV_1, - &modldrv, - NULL -}; - -static void *i2o_nexus_state; - -int -_init(void) -{ - int error; - - if ((error = ddi_soft_state_init(&i2o_nexus_state, - sizeof (struct iop_nexus_instance), 1)) != 0) - return (error); - - if ((error = mod_install(&modlinkage)) != 0) - ddi_soft_state_fini(&i2o_nexus_state); - - return (error); -} - -int -_fini(void) -{ - int error; - - if ((error = mod_remove(&modlinkage)) == 0) - ddi_soft_state_fini(&i2o_nexus_state); - - return (error); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - - -/* - * ********************************************************************** - * * bus_ops entry points * - * ********************************************************************** - */ - - -/* - * NOTE: THIS FUNCTION IS NOT APPLICABLE FOR I2O. RETURN ERROR. - */ -/*ARGSUSED*/ -static int -i2o_intr_op(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t op, - ddi_intr_handle_impl_t *hdlp, void *result) -{ - return (DDI_FAILURE); -} - -static int -i2o_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr, - int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep) -{ - /* - * Adjust DMA attributes structure as per I2O Spec version 1.5. - */ - ddi_dma_attr_merge(attr, &i2o_dma_attr); - - return (ddi_dma_allochdl(dip, rdip, attr, waitfp, arg, handlep)); -} - -static int -i2o_bus_ctl(dev_info_t *dip, dev_info_t *rdip, - ddi_ctl_enum_t opt, void *a, void *v) -{ - char name[16]; - uint_t tid; - int error; - - switch (opt) { - case DDI_CTLOPS_INITCHILD: - tid = ddi_prop_get_int(DDI_DEV_T_ANY, (dev_info_t *)a, - DDI_PROP_DONTPASS, "i2o-device-id", -1); - if (tid == (uint_t)-1) - return (DDI_FAILURE); - (void) sprintf(name, "%x", tid); - error = impl_ddi_sunbus_initchild((dev_info_t *)a); - if (error != DDI_SUCCESS) - return (DDI_FAILURE); - ddi_set_name_addr((dev_info_t *)a, name); - return (DDI_SUCCESS); - - case DDI_CTLOPS_UNINITCHILD: - impl_ddi_sunbus_removechild(a); - return (DDI_SUCCESS); - - case DDI_CTLOPS_REPORTDEV: - { - cmn_err(CE_CONT, "?%s%d at %s%d: TID %s\n", - ddi_driver_name(rdip), ddi_get_instance(rdip), - ddi_driver_name(dip), ddi_get_instance(dip), - ddi_get_name_addr(rdip)); - - return (DDI_SUCCESS); - } - - /* - * These functions shouldn't be called by the OSMs. Return error. - */ - case DDI_CTLOPS_DMAPMAPC: - case DDI_CTLOPS_SIDDEV: - case DDI_CTLOPS_SLAVEONLY: - case DDI_CTLOPS_AFFINITY: - case DDI_CTLOPS_REGSIZE: - case DDI_CTLOPS_NREGS: - case DDI_CTLOPS_POKE: - case DDI_CTLOPS_PEEK: - return (DDI_FAILURE); - - default: - /* let the parent handle the rest */ - return (ddi_ctlops(dip, rdip, opt, a, v)); - } -} - -/* - * ********************************************************************** - * * dev_ops entry points * - * ********************************************************************** - */ - -/* - * Determine if the IOP is present. - */ -static int -i2o_probe(dev_info_t *dip) -{ - ddi_acc_handle_t handle; - uint8_t base_class, sub_class, prog_class; - - if (pci_config_setup(dip, &handle) != DDI_SUCCESS) - return (DDI_PROBE_FAILURE); - - base_class = pci_config_get8(handle, PCI_CONF_BASCLASS); - sub_class = pci_config_get8(handle, PCI_CONF_SUBCLASS); - prog_class = pci_config_get8(handle, PCI_CONF_PROGCLASS); - - pci_config_teardown(&handle); - - if ((base_class != PCI_I2O_BASE_CLASS) || - (sub_class != PCI_I2O_SUB_CLASS) || - (prog_class != PCI_I2O_PROG_CLASS1)) - - return (DDI_PROBE_FAILURE); - - return (DDI_PROBE_SUCCESS); -} - -/* - * attach(9E) - */ - -static int -i2o_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) -{ - iop_nexus_instance_t *iop = NULL; - ddi_acc_handle_t handle; - int nregs; - int csr; - uint32_t base_reg0; - int instance; - - if (cmd != DDI_ATTACH) - return (DDI_FAILURE); - - if (pci_config_setup(dip, &handle) != DDI_SUCCESS) - return (DDI_FAILURE); - - /* - * turn on Master Enable and Memory Access Enable bits. - */ - csr = pci_config_get32(handle, PCI_CONF_COMM); - pci_config_put32(handle, PCI_CONF_COMM, - csr | PCI_COMM_ME | PCI_COMM_MAE); - - base_reg0 = pci_config_get32(handle, PCI_CONF_BASE0); - - ASSERT((base_reg0 & PCI_BASE_SPACE_M) == 0); - - pci_config_teardown(&handle); - - /* - * Allocate iop_nexus_instance soft state structure for this - * IOP instance. - */ - instance = ddi_get_instance(dip); - if (ddi_soft_state_zalloc(i2o_nexus_state, instance) != DDI_SUCCESS) - return (DDI_FAILURE); - iop = (iop_nexus_instance_t *)ddi_get_soft_state(i2o_nexus_state, - instance); - - iop->dip = dip; - iop->iop_state = IOP_INIT; - - /* - * Map the device memory (i.e IOP's shared local memory). - * - * ISSUE: Mapping the whole shared memory (4 to 16M) may be too - * much. But, to map the pages that we really need it requires - * reading the inbound FIFO to find out the range of offsets used - * for allocating inbound message frames by the IOP. It is possible - * to find the range of MFAs and then map only those pages. But, - * this will bring up the following issues: - * - * 1. IOP reset may reallocate the message frames so the - * range may change. (Note: currently i2o_msg_iop_init() - * does IOP reset so it will be a problem.) - * 2. I2O Spec doesn't restrict the IOP allocating inbound - * message frames dynamically. - * 3. Reading the MFAs should be done when no other external - * agent (e.g other IOPs) is accessing the IOP. - * - * This issue is addressed by the I2O Spec version 2.0 where - * IOP gives additional parameters which gives us the information - * we need to map only the pages that have the MFAs. For now, we - * will map the whole thing. - */ - - if ((ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS) || (nregs < 2) || - (ddi_dev_regsize(dip, 1, &iop->shared_memsize) != DDI_SUCCESS)) - goto cleanup; - - DEBUGF(1, (CE_CONT, "!i2o_attach: IOP shared memory size 0x%x", - (int)iop->shared_memsize)); - - if (ddi_regs_map_setup(dip, 1, &iop->iop_base_addr, 0, - iop->shared_memsize, &i2o_dev_acc_attr, - &iop->acc_handle) != DDI_SUCCESS) { - DEBUGF(1, (CE_CONT, "i2o_attach: ddi_regs_map_setup failed")); - goto cleanup; - } - - /* - * Initialize i2o_msg_trans data structure for i2o_msg module. - */ - iop->i2o_msg_trans.version = I2O_MSG_TRANS_VER; - iop->i2o_msg_trans.iop_base_addr = iop->iop_base_addr; - iop->i2o_msg_trans.iop_inbound_fifo_paddr = - (base_reg0 & PCI_BASE_M_ADDR_M) + PCI_IOP_INBOUND_FREELIST_FIFO; - iop->i2o_msg_trans.acc_handle = iop->acc_handle; - iop->i2o_msg_trans.nexus_handle = (i2o_nexus_handle_t)iop; - iop->i2o_msg_trans.iblock_cookie = iop->iblock_cookie; - iop->i2o_msg_trans.i2o_trans_msg_alloc = i2o_alloc_msg; - iop->i2o_msg_trans.i2o_trans_msg_send = i2o_send_msg; - iop->i2o_msg_trans.i2o_trans_msg_recv = i2o_recv_msg; - iop->i2o_msg_trans.i2o_trans_msg_freebuf = i2o_free_msg; - iop->i2o_msg_trans.i2o_trans_disable_intr = i2o_disable_intr; - iop->i2o_msg_trans.i2o_trans_enable_intr = i2o_enable_intr; - - /* Disable IOP interrupts */ - i2o_disable_intr((i2o_nexus_handle_t)iop); - - /* - * Register an interrupt handler for IOP interrupts. If the - * property 'iop_intr_pri' is set then use that otherwise - * set the priority to 5. - */ - iop->iop_intr_pri = ddi_prop_get_int(DDI_DEV_T_ANY, dip, - DDI_PROP_DONTPASS, "iop_intr_pri", IOP_INTR_PRI_DEFAULT); - - if (ddi_add_intr(dip, 0, &iop->iblock_cookie, &iop->idevice_cookie, - i2o_intr, (caddr_t)iop) != DDI_SUCCESS) - goto cleanup; - - /* - * Call i2o_msg_iop_init() to initialize the IOP. - */ - - cmn_err(CE_CONT, "\rI2O Nexus: Initializing IO Processor %d...", - instance); - - iop->i2o_iop_handle = i2o_msg_iop_init(dip, &iop->i2o_msg_trans); - - if (iop->i2o_iop_handle == NULL) { /* IOP Initialization failed */ - ddi_remove_intr(dip, 0, iop->iblock_cookie); - cmn_err(CE_CONT, "FAILED.\n"); - goto cleanup; - } - - cmn_err(CE_CONT, "done.\n"); - - /* Enable IOP interrupts now */ - i2o_enable_intr((i2o_nexus_handle_t)iop); - - iop->iop_state = IOP_ONLINE; /* now IOP is ready */ - - ddi_report_dev(dip); - -#ifdef I2O_DEBUG - if (i2o_nexus_debug >= 2) - dump_exec_params_0001(iop); -#endif - -#ifndef I2O_BOOT_SUPPORT - - /* - * Create the devinfo nodes for the I2O devices. - */ - i2o_create_devinfo(iop); - -#endif - return (DDI_SUCCESS); - -cleanup: - /* - * free up the allocated resources and return error. - */ - - if (iop->iop_base_addr != 0) - ddi_regs_map_free(&iop->acc_handle); - - /* free up the soft state structure for this instance */ - ddi_soft_state_free(i2o_nexus_state, instance); - - return (DDI_FAILURE); -} - -/* - * detach(9E) - */ - -static int -i2o_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) -{ - iop_nexus_instance_t *iop = NULL; - int instance; - - instance = ddi_get_instance(dip); - iop = (iop_nexus_instance_t *)ddi_get_soft_state(i2o_nexus_state, - instance); - - if (iop == NULL) - return (DDI_FAILURE); - - switch (cmd) { - case DDI_DETACH: - - /* reset the IOP */ - if (i2o_msg_iop_uninit(iop->i2o_iop_handle) != DDI_SUCCESS) - return (DDI_FAILURE); - - /* unregister the interrupt handler */ - ddi_remove_intr(dip, 0, iop->iblock_cookie); - - /* unmap the shared device memory */ - ddi_regs_map_free(&iop->acc_handle); - - /* free up the soft state structure for this instance */ - ddi_soft_state_free(i2o_nexus_state, instance); - - return (DDI_SUCCESS); - - case DDI_SUSPEND: /* XXX FIX IT LATER */ - case DDI_PM_SUSPEND: /* XXX FIX IT LATER */ - /* fall thru */ - - default: - return (DDI_FAILURE); - } -} - -/* - * IOP interrupt handler. - * - * Note: In the current I2O Spec (version 1.5) only Outbound PostList - * service interrupt is defined. So, this routine handles this - * interrupt. - * - * This function simply calls i2o_msg_process_reply_queue() to process - * the reply messages. It is assumed that the i2o_msg_process_reply_queue() - * will putback the processed messages into the freelist. - */ - -static uint_t -i2o_intr(caddr_t arg) -{ - register iop_nexus_instance_t *iop; - uint32_t intr_state; - uint32_t intr_mask; - - iop = (iop_nexus_instance_t *)arg; - - if (iop->iop_state != IOP_ONLINE) - return (DDI_INTR_UNCLAIMED); - - intr_state = ddi_get32(iop->acc_handle, - (uint32_t *)(iop->iop_base_addr + PCI_IOP_INTR_STATUS_REG)); - - intr_mask = ddi_get32(iop->acc_handle, - (uint32_t *)(iop->iop_base_addr + PCI_IOP_INTR_MASK_REG)); - - if (((intr_state & I2O_OUTBOUND_POSTLIST_SERVICE_INTR_MASK) == 0) || - ((intr_mask & I2O_OUTBOUND_POSTLIST_SERVICE_INTR_MASK) != 0)) - /* No interrupt from this IOP */ - return (DDI_INTR_UNCLAIMED); - - /* Let the I2O Message module process the reply message queue */ - i2o_msg_process_reply_queue(iop->i2o_iop_handle); - -#ifdef I2O_DEBUG - iop->intr_count++; /* debugging */ -#endif - - return (DDI_INTR_CLAIMED); -} - -/* - * *********************************************************************** - * ** Transport functions to support the I2O Message module ** - * ** ** - * ** NOTE: Locking for these functions are done within the I2O ** - * ** Message module. ** - * *********************************************************************** - */ - -/* - * Get an MFA from the Inbound FreeList FIFO. - */ -static uint_t -i2o_alloc_msg(i2o_nexus_handle_t handle) -{ - register iop_nexus_instance_t *iop; - - iop = (iop_nexus_instance_t *)handle; - - return (ddi_get32(iop->acc_handle, (uint32_t *)(iop->iop_base_addr + - PCI_IOP_INBOUND_FREELIST_FIFO))); -} - -/* - * Post the MFA to Inbound PostList FIFO. - */ -static int -i2o_send_msg(i2o_nexus_handle_t handle, uint_t mfa) -{ - register iop_nexus_instance_t *iop; - - iop = (iop_nexus_instance_t *)handle; - - if (mfa < iop->shared_memsize) { - ddi_put32(iop->acc_handle, (uint32_t *)(iop->iop_base_addr + - PCI_IOP_INBOUND_POSTLIST_FIFO), mfa); - - return (DDI_SUCCESS); - } - - return (DDI_FAILURE); /* invalid argument(s) */ -} - -/* - * Get the reply MFA from the Outbound PostList FIFO. - */ -static uint_t -i2o_recv_msg(i2o_nexus_handle_t handle) -{ - register iop_nexus_instance_t *iop; - - iop = (iop_nexus_instance_t *)handle; - - return (ddi_get32(iop->acc_handle, (uint32_t *)(iop->iop_base_addr + - PCI_IOP_OUTBOUND_POSTLIST_FIFO))); -} - -/* - * Return reply MFA to the Outbound FreeList FIFO. - */ -static void -i2o_free_msg(i2o_nexus_handle_t handle, uint_t mfa) -{ - register iop_nexus_instance_t *iop; - - iop = (iop_nexus_instance_t *)handle; - - ddi_put32(iop->acc_handle, (uint32_t *)(iop->iop_base_addr + - PCI_IOP_OUTBOUND_FREELIST_FIFO), mfa); -} - -/* - * Disable IOP hardware interrupts. Currently only bit 3 in the Interrupt - * Mask register is defined and it is for outbound postlist service - * interrupt. (See section 4.2.1.5). - */ - -static void -i2o_disable_intr(i2o_nexus_handle_t handle) -{ - register iop_nexus_instance_t *iop; - uint_t intr_mask; - - iop = (iop_nexus_instance_t *)handle; - - intr_mask = ddi_get32(iop->acc_handle, - (uint32_t *)(iop->iop_base_addr + PCI_IOP_INTR_MASK_REG)); - - ddi_put32(iop->acc_handle, - (uint32_t *)(iop->iop_base_addr + PCI_IOP_INTR_MASK_REG), - intr_mask | I2O_OUTBOUND_POSTLIST_SERVICE_INTR_MASK); -} - -/* - * Enable IOP hardware interrupts. Currently only bit 3 in the Interrupt - * Mask register is defined and it is for outbound postlist service - * interrupt. (See section 4.2.1.5). - */ - -static void -i2o_enable_intr(i2o_nexus_handle_t handle) -{ - register iop_nexus_instance_t *iop; - uint_t intr_mask; - - iop = (iop_nexus_instance_t *)handle; - - intr_mask = ddi_get32(iop->acc_handle, - (uint32_t *)(iop->iop_base_addr + PCI_IOP_INTR_MASK_REG)); - - ddi_put32(iop->acc_handle, (uint32_t *)(iop->iop_base_addr + - PCI_IOP_INTR_MASK_REG), - intr_mask & ~I2O_OUTBOUND_POSTLIST_SERVICE_INTR_MASK); -} - -#ifndef I2O_BOOT_SUPPORT - -/* - * Since we don't have boot support yet, we need to create the devinfo - * nodes for the I2O devices here. No devinfo nodes are created for - * SCSI Peripheral class devices. For adapter devices, if the adapter - * is host visible (HRT has this information) then there may be a - * devinfo node else where in the devinfo tree. For each host visible - * adapter device we need to prune any other devinfo nodes for this - * adapter in the system. - */ - -static void -i2o_create_devinfo(iop_nexus_instance_t *iop) -{ - i2o_lct_t *lct; - ddi_acc_handle_t acc_hdl; - uint_t nent; - uint_t local_tid; - uint_t user_tid; - uint_t class; - uint_t sub_class; - dev_info_t *cdip; - char *nodename, *compat_name, *dev_type; - int i; - - /* - * Step 1 - * - * Get HRT and look for any adapters that are present, assigned to - * IOP but not hidden. For each of those adapters we need to - * remove any devinfo nodes that may be present else where in - * devinfo tree. - */ - - /* - * For now, we assume that all adpaters that are controlled - * by the IOP are hidden from the host. This step can be - * implemented easily in the boot system (i.e devconf on x86) - * when that phase is implemented. - */ - - /* XXX DEFER IT FOR NOW XXX */ - - /* - * Step 2 - * - * Create the devinfo nodes for each I2O class device that - * is not claimed (i.e UserTID == 0xFFF) and is not of - * SCSI peripheral type. - */ - - i2o_msg_get_lct_info(iop->i2o_iop_handle, &lct, &acc_hdl); - nent = ((ddi_get16(acc_hdl, &lct->TableSize) << 2) - sizeof (i2o_lct_t) - + sizeof (i2o_lct_entry_t)) / sizeof (i2o_lct_entry_t); - - for (i = 0; i < nent; i++) { - - /* If the device is already claimed then continue */ - user_tid = get_lct_entry_UserTID(&lct->LCTEntry[i], acc_hdl); - if (user_tid != 0xFFF) - continue; - - class = get_lct_entry_Class(&lct->LCTEntry[i], acc_hdl); - sub_class = ddi_get32(acc_hdl, &lct->LCTEntry[i].SubClassInfo); - - switch (class) { - case I2O_CLASS_EXECUTIVE: - case I2O_CLASS_DDM: - continue; - - case I2O_CLASS_ATE_PORT: - case I2O_CLASS_ATE_PERIPHERAL: - case I2O_CLASS_FLOPPY_CONTROLLER: - case I2O_CLASS_FLOPPY_DEVICE: - case I2O_CLASS_SEQUENTIAL_STORAGE: - case I2O_CLASS_LAN: - case I2O_CLASS_WAN: - case I2O_CLASS_FIBRE_CHANNEL_PORT: - case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL: - /* For now, ingore these types */ - continue; - - case I2O_CLASS_SCSI_PERIPHERAL: - continue; - - case I2O_CLASS_RANDOM_BLOCK_STORAGE: - nodename = "disk"; - compat_name = "i2o_bs"; - dev_type = "block"; - break; - case I2O_CLASS_BUS_ADAPTER_PORT: - nodename = "adapter"; - compat_name = "i2o_scsi"; - /* - * sub_class should indicate the type of bus. - * XXX Check this with Symbios. - */ - if (sub_class == 0x3) - dev_type = "scsi-3"; - else if (sub_class == 0x2) - dev_type = "scsi-2"; - else - dev_type = "scsi"; - break; - default: - continue; - } - - local_tid = get_lct_entry_LocalTID(&lct->LCTEntry[i], acc_hdl); - - cdip = NULL; - - /* create the devinfo node */ - if (ndi_devi_alloc(iop->dip, nodename, - (pnode_t)DEVI_SID_NODEID, &cdip) != NDI_SUCCESS) { - cmn_err(CE_WARN, - "i2o_create_devinfo: ndi_devi_alloc failed"); - goto fail; - } - - /* create the properties */ - - if (ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "i2o-device-id", - local_tid) != DDI_PROP_SUCCESS) - goto fail; - if (ndi_prop_update_string(DDI_DEV_T_NONE, cdip, "device-type", - dev_type) != DDI_PROP_SUCCESS) - goto fail; - if (ndi_prop_update_string(DDI_DEV_T_NONE, cdip, - "compatible", compat_name) != DDI_PROP_SUCCESS) - goto fail; - - /* now, attach the driver */ - (void) ndi_devi_online(cdip, NDI_ONLINE_ATTACH); - } - - return; - -fail: - if (cdip != NULL) { - (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, "i2o-device-id"); - (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, "compatible"); - (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, "device-type"); - if (ndi_devi_free(cdip) != NDI_SUCCESS) { - cmn_err(CE_WARN, - "i2o_create_devinfo: ndi_devi_free failed"); - } - } -} - -#endif - -#ifdef I2O_DEBUG - -static ddi_dma_attr_t i2o_dma_attr_contig = { - DMA_ATTR_VERSION, /* version number */ - (uint64_t)0, /* low DMA address range */ - (uint64_t)0xFFFFFFFF, /* high DMA address range */ - (uint64_t)0x00FFFFFF, /* DMA counter register */ - 1, /* DMA address alignment */ - 1, /* DMA burstsizes */ - 1, /* min effective DMA size */ - (uint64_t)0xFFFFFFFF, /* max DMA xfer size */ - (uint64_t)0xFFFFFFFF, /* segment boundary */ - 0x1, /* s/g length */ - 1, /* granularity of device */ - 0 /* Bus specific DMA flags */ -}; - -kmutex_t test_mutex; -kcondvar_t test_cv; -volatile int test_result; - -static void -dump_exec_params_0001(iop_nexus_instance_t *iop) -{ - ddi_dma_handle_t dma_handle = NULL; - ddi_acc_handle_t acc_hdl, acc_hdl2; - size_t real_length; - ddi_dma_cookie_t dma_cookie; - uint_t ncookies; - caddr_t buf = NULL; - uint32_t ops_block_size, results_block_size; - i2o_util_params_get_message_t *msgp; - i2o_sge_simple_element_t *sgl; - /* operations block info */ - i2o_param_operations_list_header_t *ops_block_head; - i2o_param_operation_all_template_t *ops_block; - /* scalar parameters */ - i2o_exec_iop_message_if_scalar_t *message_if; - i2o_msg_handle_t msg_handle; - - /* allocate a DMA handle */ - if (ddi_dma_alloc_handle(iop->dip, &i2o_dma_attr_contig, DDI_DMA_SLEEP, - NULL, &dma_handle) != DDI_SUCCESS) { - goto cleanup; - } - - ops_block_size = sizeof (*ops_block_head) + sizeof (*ops_block); - - results_block_size = - sizeof (i2o_param_results_list_header_t) + - sizeof (i2o_param_read_operation_result_t) + - sizeof (*message_if) + - sizeof (i2o_param_error_info_template_t); - - /* Allocate a buffer for operation block */ - if (ddi_dma_mem_alloc(dma_handle, ops_block_size + results_block_size, - &i2o_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, - &buf, &real_length, &acc_hdl) != DDI_SUCCESS) { - goto cleanup; - } - - bzero((caddr_t)buf, real_length); - - if (ddi_dma_addr_bind_handle(dma_handle, NULL, buf, - real_length, DDI_DMA_READ | DDI_DMA_STREAMING, DDI_DMA_SLEEP, - NULL, &dma_cookie, &ncookies) != DDI_SUCCESS) { - - DEBUGF(1, (CE_CONT, - "dump_exec_params_0001: cannot bind memory")); - goto cleanup; - } - - DEBUGF(1, (CE_CONT, - "dump_exec_params_0001: dma_bind (vaddr %p paddr %x length %x)", - (void *)buf, dma_cookie.dmac_address, - (int)dma_cookie.dmac_size)); - - ops_block_head = (i2o_param_operations_list_header_t *)buf; - ops_block = (i2o_param_operation_all_template_t *) - (buf + sizeof (*ops_block_head)); - - /* initialize the operations block header */ - ddi_put16(acc_hdl, &ops_block_head->OperationCount, 1); - - /* initialize operations block for group 0001 */ - ddi_put16(acc_hdl, &ops_block[0].Operation, - I2O_PARAMS_OPERATION_FIELD_GET); - ddi_put16(acc_hdl, &ops_block[0].GroupNumber, - I2O_EXEC_IOP_MESSAGE_IF_GROUP_NO); - ddi_put16(acc_hdl, &ops_block[0].FieldCount, -1); /* all fields */ - - /* allocate the message frame */ - if (i2o_msg_alloc(iop->i2o_iop_handle, I2O_MSG_SLEEP, NULL, - (void **)&msgp, &msg_handle, &acc_hdl2) != DDI_SUCCESS) { - DEBUGF(1, (CE_CONT, - "dump_exec_params_0001: i2o_msg_alloc failed")); - (void) ddi_dma_unbind_handle(dma_handle); - goto cleanup; - } - - /* construct the UtilParamsGet message */ - msgp->StdMessageFrame.VersionOffset = I2O_VERSION_11; - msgp->StdMessageFrame.MsgFlags = 0; - ddi_put16(acc_hdl2, &msgp->StdMessageFrame.MessageSize, - (sizeof (i2o_util_params_get_message_t) + - sizeof (i2o_sg_element_t)) >> 2); - put_msg_Function(&msgp->StdMessageFrame, I2O_UTIL_PARAMS_GET, acc_hdl2); - put_msg_InitiatorAddress(&msgp->StdMessageFrame, - I2O_HOST_TID, acc_hdl2); - put_msg_TargetAddress(&msgp->StdMessageFrame, - I2O_IOP_TID, acc_hdl2); - ddi_put32(acc_hdl2, - &msgp->StdMessageFrame.InitiatorContext.initiator_context_32bits, - (uint32_t)i2o_msg_reply); - - sgl = msgp->SGL.u1.Simple; - - put_flags_count_Flags(&sgl->FlagsCount, I2O_SGL_FLAGS_END_OF_BUFFER | - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT, acc_hdl2); - put_flags_count_Count(&sgl->FlagsCount, ops_block_size, acc_hdl2); - ddi_put32(acc_hdl2, &sgl->PhysicalAddress, - (uint_t)dma_cookie.dmac_address); - - put_flags_count_Flags(&sgl[1].FlagsCount, - I2O_SGL_FLAGS_LAST_ELEMENT | - I2O_SGL_FLAGS_END_OF_BUFFER | - I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT, acc_hdl2); - put_flags_count_Count(&sgl[1].FlagsCount, - results_block_size, acc_hdl2); - ddi_put32(acc_hdl2, &sgl[1].PhysicalAddress, - (uint_t)dma_cookie.dmac_address + ops_block_size); - - mutex_init(&test_mutex, NULL, MUTEX_DRIVER, NULL); - cv_init(&test_cv, NULL, CV_DEFAULT, NULL); - - mutex_enter(&test_mutex); - - test_result = 0; - - /* send the message to the IOP */ - (void) i2o_msg_send(iop->i2o_iop_handle, (void *)msgp, msg_handle); - - /* wait for the reply */ - if (test_result == 0) - cv_wait(&test_cv, &test_mutex); - - mutex_exit(&test_mutex); - - (void) ddi_dma_unbind_handle(dma_handle); - - /* - * ************************************************************** - * Now, print all the parameters. - * ************************************************************** - */ - - /* group 0001h - Message Interface */ - - message_if = (i2o_exec_iop_message_if_scalar_t *) - (buf + ops_block_size + - sizeof (i2o_param_results_list_header_t) + - sizeof (i2o_param_read_operation_result_t)); - cmn_err(CE_CONT, - "?IOP Message Interface Parameters - Group 0001h:"); - cmn_err(CE_CONT, "?\tInboundFrameSize: %x\n", ddi_get32(acc_hdl, - &message_if->InboundFrameSize)); - cmn_err(CE_CONT, "?\tInboundSizeTarget: %x\n", ddi_get32(acc_hdl, - &message_if->InboundSizeTarget)); - cmn_err(CE_CONT, "?\tInboundMax: %x\n", ddi_get32(acc_hdl, - &message_if->InboundMax)); - cmn_err(CE_CONT, "?\tInboundTarget: %x\n", ddi_get32(acc_hdl, - &message_if->InboundTarget)); - cmn_err(CE_CONT, "?\tInboundPoolCount: %x\n", ddi_get32(acc_hdl, - &message_if->InboundPoolCount)); - cmn_err(CE_CONT, "?\tInboundCurrentFree: %x\n", ddi_get32(acc_hdl, - &message_if->InboundCurrentFree)); - cmn_err(CE_CONT, "?\tInboundCurrentPost: %x\n", ddi_get32(acc_hdl, - &message_if->InboundCurrentPost)); - cmn_err(CE_CONT, "?\tStaticCount: %x\n", ddi_get16(acc_hdl, - &message_if->StaticCount)); - cmn_err(CE_CONT, "?\tStaticInstanceCount: %x\n", ddi_get16(acc_hdl, - &message_if->StaticInstanceCount)); - cmn_err(CE_CONT, "?\tStaticLimit: %x\n", ddi_get16(acc_hdl, - &message_if->StaticLimit)); - cmn_err(CE_CONT, "?\tStaticInstanceLimit: %x\n", ddi_get16(acc_hdl, - &message_if->StaticInstanceLimit)); - cmn_err(CE_CONT, "?\tOutboundFrameSize: %x\n", ddi_get32(acc_hdl, - &message_if->OutboundFrameSize)); - cmn_err(CE_CONT, "?\tOutboundMax: %x\n", ddi_get32(acc_hdl, - &message_if->OutboundMax)); - cmn_err(CE_CONT, "?\tOutboundTarget: %x\n", ddi_get32(acc_hdl, - &message_if->OutboundMaxTarget)); - cmn_err(CE_CONT, "?\tOutboundCurrentFree: %x\n", ddi_get32(acc_hdl, - &message_if->OutboundCurrentFree)); - cmn_err(CE_CONT, "?\tInboundCurrentPost: %x\n", ddi_get32(acc_hdl, - &message_if->InboundCurrentPost)); - cmn_err(CE_CONT, "?\tInitCode: %x\n", message_if->InitCode); - -cleanup: - if (buf != NULL) - ddi_dma_mem_free(&acc_hdl); - - if (dma_handle != NULL) - ddi_dma_free_handle(&dma_handle); -} - -void -i2o_msg_reply(void *m, ddi_acc_handle_t acc_hdl) -{ - i2o_single_reply_message_frame_t *rmp; - - mutex_enter(&test_mutex); - - rmp = (i2o_single_reply_message_frame_t *)m; - if (rmp->ReqStatus != I2O_REPLY_STATUS_SUCCESS) { - cmn_err(CE_CONT, "i2o_msg_reply: Reply Message Frame:"); - cmn_err(CE_CONT, - "?Reply Message Frame (Function %x):", - get_msg_Function(&rmp->StdMessageFrame, acc_hdl)); - cmn_err(CE_CONT, - "?\tReqStatus: %x DetailedStatusCode %x\n", rmp->ReqStatus, - ddi_get16(acc_hdl, &rmp->DetailedStatusCode)); - } - - test_result = 1; - - cv_broadcast(&test_cv); - - mutex_exit(&test_mutex); -} -#endif diff --git a/usr/src/uts/common/io/i2o/pci_to_i2o.conf b/usr/src/uts/common/io/i2o/pci_to_i2o.conf deleted file mode 100644 index 73b57c346e..0000000000 --- a/usr/src/uts/common/io/i2o/pci_to_i2o.conf +++ /dev/null @@ -1,42 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 1998 by Sun Microsystems, Inc. -# All rights reserved. -# - -#pragma ident "%Z%%M% %I% %E% SMI" - -# Configuration properties for the I2O Nexus driver. -# -# ob-msg-queue-length -# Specifies the number of outbound message frames to be allocated. -# The minimum is 16. Since the max. size is determined by the IOP -# the system will set this parameter upto that maximum. -# -# ob-msg-frame-size -# Specifies the size in bytes of the outbound message frame. The -# minimum size 64 bytes. -# - -ob-msg-frame-size=64 ob-msg-queue-length=128; diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile index c00a178991..6b1b5bb8c3 100644 --- a/usr/src/uts/common/sys/Makefile +++ b/usr/src/uts/common/sys/Makefile @@ -934,15 +934,6 @@ PCHDRS= \ pit.h \ rtc.h -# I2O header files (currently used only on i386) -I2OHDRS= \ - i2oadptr.h \ - i2obscsi.h \ - i2oexec.h \ - i2omsg.h \ - i2omstr.h \ - i2outil.h - NXGEHDRS= \ nxge.h \ nxge_common.h \ diff --git a/usr/src/uts/common/sys/Makefile.syshdrs b/usr/src/uts/common/sys/Makefile.syshdrs index 6aa0c8e295..26970f5219 100644 --- a/usr/src/uts/common/sys/Makefile.syshdrs +++ b/usr/src/uts/common/sys/Makefile.syshdrs @@ -1,5 +1,24 @@ # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -129,7 +148,7 @@ sparc_ROOTDIRS= $(ROOTDKTPDIR) $(ROOTDIR)/scsi/adapters \ $(ROOTDIR)/av i386_ROOTDIRS= $(ROOTDKTPDIR) $(ROOTDIR)/scsi/adapters $(ROOTDIR)/scsi/targets \ - $(ROOTDIR)/i2o $(ROOTDIR)/agp $(ROOTDIR)/sata + $(ROOTDIR)/agp $(ROOTDIR)/sata ROOTDIRS= \ $(ROOTDIR) \ @@ -244,7 +263,6 @@ ROOTRSMHDRS= $(RSMHDRS:%=$(ROOTDIR)/rsm/%) ROOTSDKTPHDRS= $(SDKTPHDRS:%=$(ROOTDIR)/dktp/%) ROOTDKTPHDRS= $(DKTPHDRS:%=$(ROOTDIR)/dktp/%) ROOTPCHDRS= $(PCHDRS:%=$(ROOTDIR)/%) -ROOTI2OHDRS= $(I2OHDRS:%=$(ROOTDIR)/i2o/%) ROOTHOTPLUGHDRS= $(HOTPLUGHDRS:%=$(ROOTDIR)/hotplug/%) ROOTHOTPLUGPCIHDRS= $(HOTPLUGPCIHDRS:%=$(ROOTDIR)/hotplug/pci/%) @@ -258,7 +276,7 @@ sparc_ROOTHDRS= $(ROOTSDKTPHDRS) $(ROOTSCSICADHDRS) $(ROOTSCSITARGETSHDRS) \ i386_ROOTHDRS= $(ROOTDKTPHDRS) $(ROOTPCHDRS) $(ROOTSCSITARGETSHDRS) \ $(ROOTSCSIVHCIHDRS) $(ROOTFCHDRS) \ - $(ROOTI2OHDRS) $(ROOTPCMCIAHDRS) $(ROOTHOTPLUGHDRS) \ + $(ROOTPCMCIAHDRS) $(ROOTHOTPLUGHDRS) \ $(ROOTHOTPLUGPCIHDRS) $(ROOTSATAGENHDRS) # install rules diff --git a/usr/src/uts/common/sys/i2o/i2oadptr.h b/usr/src/uts/common/sys/i2o/i2oadptr.h deleted file mode 100644 index 0dd0f70801..0000000000 --- a/usr/src/uts/common/sys/i2o/i2oadptr.h +++ /dev/null @@ -1,323 +0,0 @@ -/* - * **************************************************************************** - * I2O SIG All rights reserved. - * - * These header files are provided, pursuant to your I2O SIG membership - * agreement, free of charge on an as-is basis without warranty of any kind, - * either express or implied, including but not limited to, implied warranties - * or merchantability and fitness for a particular purpose. I2O SIG does not - * warrant that this program will meet the user's requirements or that the - * operation of these programs will be uninterrupted or error-free. - * Acceptance and use of this program constitutes the user's understanding - * that he will have no recourse to I2O SIG for any actual or consequential - * damages including, but not limited to, loss profits arising out of use - * or inability to use this program. - * - * Member is permitted to create derivative works to this header-file program. - * However, all copies of the program and its derivative works must contain the - * I2O SIG copyright notice. - * - * **************************************************************************** - */ - -/* - * ************************************************************************** - * - * i2oadptr.h -- I2O Adapter Class Message defintion file - * - * This file contains information presented in Chapter 6 of - * the I2o Specification. - * - * *************************************************************************** - */ - -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_I2OADPTR_H -#define _SYS_I2OADPTR_H - -#pragma ident "%W% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#define I2OADPTR_REV 1_5_1 /* Header file revision string */ - -/* - * NOTES: See i2omsg.h for more info - */ - -#include <sys/i2o/i2omsg.h> /* Include the Base Message file */ -#include <sys/types.h> /* For system types defines */ - - - -/* - * BUS ADAPTER CLASS SPECIFIC FUNCTIONS - */ - -#define I2O_HBA_ADAPTER_RESET 0x85 -#define I2O_HBA_BUS_QUIESCE 0x8b -#define I2O_HBA_BUS_RESET 0x87 -#define I2O_HBA_BUS_SCAN 0x89 - - -/* - * Detailed Status Codes for HBA operations - * - * Note: - * The 16-bit Detailed Status Code field for HBA operations is divided - * into two separate 8-bit fields. The lower 8 bits are reserved. The - * upper 8 bits are used to report Adapter Status information. The - * definitions for these two fields, however, will be consistent with - * the standard reply message frame structure declaration, which treats - * this as a single 16-bit field. In addition, the values used will be - * consistent with the Adapter Status codes defined for the SCSI - * Peripheral class. Theses codes are based on CAM-1. In other words, - * these definitions are a subset of the SCSI peripheral class codes. - * Where applicable, "SCSI" has been removed from the definition. - * - */ - -#define I2O_HBA_DSC_MASK 0xFF00 - -#define I2O_HBA_DSC_SUCCESS 0x0000 -#define I2O_HBA_DSC_ADAPTER_BUSY 0x0500 -#define I2O_HBA_DSC_COMMAND_TIMEOUT 0x0B00 -#define I2O_HBA_DSC_COMPLETE_WITH_ERROR 0x0400 -#define I2O_HBA_DSC_FUNCTION_UNAVAILABLE 0x3A00 -#define I2O_HBA_DSC_NO_ADAPTER 0x1100 -#define I2O_HBA_DSC_PARITY_ERROR_FAILURE 0x0F00 -#define I2O_HBA_DSC_PATH_INVALID 0x0700 -#define I2O_HBA_DSC_PROVIDE_FAILURE 0x1600 -#define I2O_HBA_DSC_QUEUE_FROZEN 0x4000 -#define I2O_HBA_DSC_REQUEST_ABORTED 0x0200 -#define I2O_HBA_DSC_REQUEST_INVALID 0x0600 -#define I2O_HBA_DSC_REQUEST_LENGTH_ERROR 0x1500 -#define I2O_HBA_DSC_REQUEST_TERMINATED 0x1800 -#define I2O_HBA_DSC_RESOURCE_UNAVAILABLE 0x3400 -#define I2O_HBA_DSC_BUS_BUSY 0x3F00 -#define I2O_HBA_DSC_BUS_RESET 0x0E00 -#define I2O_HBA_DSC_ID_INVALID 0x3900 -#define I2O_HBA_DSC_SEQUENCE_FAILURE 0x1400 -#define I2O_HBA_DSC_UNABLE_TO_ABORT 0x0300 -#define I2O_HBA_DSC_UNABLE_TO_TERMINATE 0x0900 -#define I2O_HBA_DSC_UNACKNOWLEDGED_EVENT 0x3500 -#define I2O_HBA_DSC_UNEXPECTED_BUS_FREE 0x1300 - -/* - * Bus Adapter Parameter Groups - */ - -#define I2O_HBA_CONTROLLER_INFO_GROUP_NO 0x0000 -#define I2O_HBA_HISTORICAL_STATS_GROUP_NO 0x0100 -#define I2O_HBA_SCSI_CONTROLLER_INFO_GROUP_NO 0x0200 -#define I2O_HBA_SCSI_BUS_PORT_INFO_GROUP_NO 0x0201 -#define I2O_HBA_FCA_CONTROLLER_INFO_GROUP_NO 0x0300 -#define I2O_HBA_FCA_PORT_INFO_GROUP_NO 0x0301 - -/* - * - 0000h - HBA Controller Information Parameter Group - */ - -/* - * Bus Type - */ - -#define I2O_HBA_BUS_TYPE_GENERIC 0x00 -#define I2O_HBA_BUS_TYPE_SCSI 0x01 -#define I2O_HBA_BUS_TYPE_FCA 0x10 - -typedef struct i2o_hba_controller_info_scalar { - uint8_t BusType; - uint8_t BusState; - uint16_t Reserved2; - uint8_t BusName[12]; -} i2o_hba_controller_info_scalar_t; - -/* - * - 0100h - HBA Historical Stats Parameter Group - */ - -typedef struct i2o_hba_hist_stats_scalar { - uint32_t TimeLastPoweredUp; - uint32_t TimeLastReset; -} i2o_hba_hist_stats_scalar_t; - -/* - * - 0200h - HBA SCSI Controller Information Parameter Group - */ - -/* - * SCSI Type - */ - -#define I2O_SCSI_TYPE_UNKNOWN 0x00 -#define I2O_SCSI_TYPE_SCSI_1 0x01 -#define I2O_SCSI_TYPE_SCSI_2 0x02 -#define I2O_SCSI_TYPE_SCSI_3 0x03 - -/* - * Protection Management - */ - -#define I2O_SCSI_PORT_PROT_OTHER 0x00 -#define I2O_SCSI_PORT_PROT_UNKNOWN 0x01 -#define I2O_SCSI_PORT_PROT_UNPROTECTED 0x02 -#define I2O_SCSI_PORT_PROT_PROTECTED 0x03 -#define I2O_SCSI_PORT_PROT_SCC 0x04 - -/* - * Settings - */ - -#define I2O_SCSI_PORT_PARITY_FLAG 0x01 -#define I2O_SCSI_PORT_PARITY_DISABLED 0x00 -#define I2O_SCSI_PORT_PARITY_ENABLED 0x01 - -#define I2O_SCSI_PORT_SCAN_ORDER_FLAG 0x02 -#define I2O_SCSI_PORT_SCAN_LOW_TO_HIGH 0x00 -#define I2O_SCSI_PORT_SCAN_HIGH_TO_LOW 0x02 - -#define I2O_SCSI_PORT_IID_FLAG 0x04 -#define I2O_SCSI_PORT_IID_DEFAULT 0x00 -#define I2O_SCSI_PORT_IID_SPECIFIED 0x04 - -#define I2O_SCSI_PORT_SCAM_FLAG 0x08 -#define I2O_SCSI_PORT_SCAM_DISABLED 0x00 -#define I2O_SCSI_PORT_SCAM_ENABLED 0x08 - -#define I2O_SCSI_PORT_TYPE_FLAG 0x80 -#define I2O_SCSI_PORT_TYPE_PARALLEL 0x00 -#define I2O_SCSI_PORT_TYPE_SERIAL 0x80 - -typedef struct i2o_hba_scsi_controller_info_scalar { - uint8_t SCSIType; - uint8_t ProtectionManagement; - uint8_t Settings; - uint8_t Reserved1; - uint32_t InitiatorID; - uint64_t ScanLun0Only; - uint16_t DisableDevice; - uint8_t MaxOffset; - uint8_t MaxDataWidth; - uint64_t MaxSyncRate; -} i2o_hba_scsi_controller_info_scalar_t; - -/* - * - 0201h - HBA SCSI Bus Port Information Parameter Group - */ - -/* - * NOTE: Refer to the SCSI Peripheral Class Bus Port Information - * Parameter Group field definitions for HBA SCSI Bus Port - * field definitions. - */ - -typedef struct i2o_hba_scsi_bus_port_info_scalar { - uint8_t PhysicalInterface; - uint8_t ElectricalInterface; - uint8_t Isochronous; - uint8_t ConnectorType; - uint8_t ConnectorGender; - uint8_t Reserved1; - uint16_t Reserved2; - uint32_t MaxNumberDevices; - uint32_t DeviceIdBegin; - uint32_t DeviceIdEnd; - uint8_t LunBegin[8]; - uint8_t LunEnd[8]; -} i2o_hba_scsi_bus_port_info_scalar_t; - -/* - * - 0300h - HBA FCA Controller Information Parameters Group defines - */ - -/* - * SCSI Type - */ - -#define I2O_FCA_TYPE_UNKNOWN 0x00 -#define I2O_FCA_TYPE_FCAL 0x01 - -typedef struct i2o_hba_fca_controller_info_scalar { - uint8_t FcaType; - uint8_t Reserved1; - uint16_t Reserved2; -} i2o_hba_fca_controller_info_scalar_t; - -/* - * - 0301h - HBA FCA Port Information Parameters Group defines - */ - -typedef struct i2o_hba_fca_port_info_scalar { - uint32_t Reserved4; -} i2o_hba_fca_port_info_scalar_t; - -/* - * I2O BUS ADAPTER CLASS SPECIFIC MESSAGE DEFINITIONS - */ - -/* - * I2O Bus Adapter Class Reply Message Frame - */ - -typedef struct i2o_hba_reply_message_frame { - i2o_single_reply_message_frame_t StdReplyFrame; -} i2o_hba_reply_message_frame_t; - -/* - * I2O HBA Adapter Reset Message Frame - */ - -typedef struct i2o_hba_adapter_reset_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_hba_adapter_reset_message_t; - -/* - * I2O HBA Bus Quiesce Message Frame - */ - -typedef uint32_t i2o_hbq_flags_t; - -#define I2O_HBQ_FLAG_NORMAL 0x0000 -#define I2O_HBQ_FLAG_QUIESCE 0x0001 - -typedef struct i2o_hba_bus_quiesce_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_hbq_flags_t Flags; -} i2o_hba_bus_quiesce_message_t; - -/* - * I2O HBA Bus Reset Message Frame - */ - -typedef struct i2o_hba_bus_reset_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_hba_bus_reset_message_t; - -/* - * I2O HBA Bus Scan Message Frame - */ - -/* - * NOTE: SCSI-2 8-bit scalar LUN goes into offset 1 of Lun arrays - */ - -typedef struct i2o_hba_bus_scan_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_hba_bus_scan_message_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_I2OADPTR_H */ diff --git a/usr/src/uts/common/sys/i2o/i2obscsi.h b/usr/src/uts/common/sys/i2o/i2obscsi.h deleted file mode 100644 index 8cb3d33338..0000000000 --- a/usr/src/uts/common/sys/i2o/i2obscsi.h +++ /dev/null @@ -1,400 +0,0 @@ -/* - * ***************************************************************************** - * I2O SIG All rights reserved. - * - * These header files are provided, pursuant to your I2O SIG membership - * agreement, free of charge on an as-is basis without warranty of any kind, - * either express or implied, including but not limited to, implied warranties - * or merchantability and fitness for a particular purpose. I2O SIG does not - * warrant that this program will meet the user's requirements or that the - * operation of these programs will be uninterrupted or error-free. - * Acceptance and use of this program constitutes the user's understanding - * that he will have no recourse to I2O SIG for any actual or consequential - * damages including, but not limited to, loss profits arising out of use - * or inability to use this program. - * - * Member is permitted to create derivative works to this header-file program. - * However, all copies of the program and its derivative works must contain the - * I2O SIG copyright notice. - * - * ***************************************************************************** - */ - -/* - * *************************************************************************** - * - * I2OBSCSI.h -- I2O Base SCSI Device Class Message defintion file - * - * This file contains information presented in Chapter 6, Section 6 & 7 of - * the I2O Specification. - * - * *************************************************************************** - */ - -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_I2OBSCSI_H -#define _SYS_I2OBSCSI_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#define I2OBSCSI_REV 1_5_1 /* Header file revision string */ - -/* - * NOTES: See i2omsg.h for more info - */ - -#include <sys/i2o/i2omsg.h> /* Include the Base Message file */ -#include <sys/types.h> /* For system types defined */ - -/* - * SCSI Peripheral Class specific functions - * - * Although the names are SCSI Peripheral class specific, the values - * assigned are common with other classes when applicable. - */ - -#define I2O_SCSI_DEVICE_RESET 0x27 -#define I2O_SCSI_SCB_ABORT 0x83 -#define I2O_SCSI_SCB_EXEC 0x81 - -/* - * Detailed Status Codes for SCSI operations - * - * The 16-bit Detailed Status Code field for SCSI operations is divided - * into two separate 8-bit fields. The lower 8 bits are used to report - * Device Status information. The upper 8 bits are used to report - * Adapter Status information. The definitions for these two fields, - * however, will be consistent with the standard reply message frame - * structure declaration, which treats this as a single 16-bit field. - */ - - -/* - * SCSI Device Completion Status Codes (defined by SCSI-2/3) - */ - -#define I2O_SCSI_DEVICE_DSC_MASK 0x00FF - -#define I2O_SCSI_DSC_SUCCESS 0x0000 -#define I2O_SCSI_DSC_CHECK_CONDITION 0x0002 -#define I2O_SCSI_DSC_BUSY 0x0008 -#define I2O_SCSI_DSC_RESERVATION_CONFLICT 0x0018 -#define I2O_SCSI_DSC_COMMAND_TERMINATED 0x0022 -#define I2O_SCSI_DSC_TASK_SET_FULL 0x0028 -#define I2O_SCSI_DSC_ACA_ACTIVE 0x0030 - -/* - * SCSI Adapter Status Codes (based on CAM-1) - */ - -#define I2O_SCSI_HBA_DSC_MASK 0xFF00 - -#define I2O_SCSI_HBA_DSC_SUCCESS 0x0000 - -#define I2O_SCSI_HBA_DSC_REQUEST_ABORTED 0x0200 -#define I2O_SCSI_HBA_DSC_UNABLE_TO_ABORT 0x0300 -#define I2O_SCSI_HBA_DSC_COMPLETE_WITH_ERROR 0x0400 -#define I2O_SCSI_HBA_DSC_ADAPTER_BUSY 0x0500 -#define I2O_SCSI_HBA_DSC_REQUEST_INVALID 0x0600 -#define I2O_SCSI_HBA_DSC_PATH_INVALID 0x0700 -#define I2O_SCSI_HBA_DSC_DEVICE_NOT_PRESENT 0x0800 -#define I2O_SCSI_HBA_DSC_UNABLE_TO_TERMINATE 0x0900 -#define I2O_SCSI_HBA_DSC_SELECTION_TIMEOUT 0x0A00 -#define I2O_SCSI_HBA_DSC_COMMAND_TIMEOUT 0x0B00 - -#define I2O_SCSI_HBA_DSC_MR_MESSAGE_RECEIVED 0x0D00 -#define I2O_SCSI_HBA_DSC_SCSI_BUS_RESET 0x0E00 -#define I2O_SCSI_HBA_DSC_PARITY_ERROR_FAILURE 0x0F00 -#define I2O_SCSI_HBA_DSC_AUTOSENSE_FAILED 0x1000 -#define I2O_SCSI_HBA_DSC_NO_ADAPTER 0x1100 -#define I2O_SCSI_HBA_DSC_DATA_OVERRUN 0x1200 -#define I2O_SCSI_HBA_DSC_UNEXPECTED_BUS_FREE 0x1300 -#define I2O_SCSI_HBA_DSC_SEQUENCE_FAILURE 0x1400 -#define I2O_SCSI_HBA_DSC_REQUEST_LENGTH_ERROR 0x1500 -#define I2O_SCSI_HBA_DSC_PROVIDE_FAILURE 0x1600 -#define I2O_SCSI_HBA_DSC_BDR_MESSAGE_SENT 0x1700 -#define I2O_SCSI_HBA_DSC_REQUEST_TERMINATED 0x1800 - -#define I2O_SCSI_HBA_DSC_IDE_MESSAGE_SENT 0x3300 -#define I2O_SCSI_HBA_DSC_RESOURCE_UNAVAILABLE 0x3400 -#define I2O_SCSI_HBA_DSC_UNACKNOWLEDGED_EVENT 0x3500 -#define I2O_SCSI_HBA_DSC_MESSAGE_RECEIVED 0x3600 -#define I2O_SCSI_HBA_DSC_INVALID_CDB 0x3700 -#define I2O_SCSI_HBA_DSC_LUN_INVALID 0x3800 -#define I2O_SCSI_HBA_DSC_SCSI_TID_INVALID 0x3900 -#define I2O_SCSI_HBA_DSC_FUNCTION_UNAVAILABLE 0x3A00 -#define I2O_SCSI_HBA_DSC_NO_NEXUS 0x3B00 -#define I2O_SCSI_HBA_DSC_SCSI_IID_INVALID 0x3C00 -#define I2O_SCSI_HBA_DSC_CDB_RECEIVED 0x3D00 -#define I2O_SCSI_HBA_DSC_LUN_ALREADY_ENABLED 0x3E00 -#define I2O_SCSI_HBA_DSC_BUS_BUSY 0x3F00 - -#define I2O_SCSI_HBA_DSC_QUEUE_FROZEN 0x4000 - -/* - * SCSI Peripheral Device Parameter Groups - */ - -/* - * SCSI Configuration and Operating Structures and Defines - */ - -#define I2O_SCSI_DEVICE_INFO_GROUP_NO 0x0000 -#define I2O_SCSI_DEVICE_BUS_PORT_INFO_GROUP_NO 0x0001 - -/* - * - 0000h - SCSI Device Information Parameters Group defines - */ - -/* - * Device Type - */ - -#define I2O_SCSI_DEVICE_TYPE_DIRECT 0x00 -#define I2O_SCSI_DEVICE_TYPE_SEQUENTIAL 0x01 -#define I2O_SCSI_DEVICE_TYPE_PRINTER 0x02 -#define I2O_SCSI_DEVICE_TYPE_PROCESSOR 0x03 -#define I2O_SCSI_DEVICE_TYPE_WORM 0x04 -#define I2O_SCSI_DEVICE_TYPE_CDROM 0x05 -#define I2O_SCSI_DEVICE_TYPE_SCANNER 0x06 -#define I2O_SCSI_DEVICE_TYPE_OPTICAL 0x07 -#define I2O_SCSI_DEVICE_TYPE_MEDIA_CHANGER 0x08 -#define I2O_SCSI_DEVICE_TYPE_COMM 0x09 -#define I2O_SCSI_DEVICE_GRAPHICS_1 0x0A -#define I2O_SCSI_DEVICE_GRAPHICS_2 0x0B -#define I2O_SCSI_DEVICE_TYPE_ARRAY_CONT 0x0C -#define I2O_SCSI_DEVICE_TYPE_UNKNOWN 0x1F - -/* - * Flags - */ - -#define I2O_SCSI_PERIPHERAL_TYPE_FLAG 0x01 -#define I2O_SCSI_PERIPHERAL_TYPE_PARALLEL 0x00 -#define I2O_SCSI_PERIPHERAL_TYPE_SERIAL 0x01 - -#define I2O_SCSI_RESERVED_FLAG 0x02 - -#define I2O_SCSI_DISCONNECT_FLAG 0x04 -#define I2O_SCSI_DISABLE_DISCONNECT 0x00 -#define I2O_SCSI_ENABLE_DISCONNECT 0x04 - -#define I2O_SCSI_MODE_MASK 0x18 -#define I2O_SCSI_MODE_SET_DATA 0x00 -#define I2O_SCSI_MODE_SET_DEFAULT 0x08 -#define I2O_SCSI_MODE_SET_SAFEST 0x10 - -#define I2O_SCSI_DATA_WIDTH_MASK 0x60 -#define I2O_SCSI_DATA_WIDTH_8 0x00 -#define I2O_SCSI_DATA_WIDTH_16 0x20 -#define I2O_SCSI_DATA_WIDTH_32 0x40 - -#define I2O_SCSI_SYNC_NEGOTIATION_FLAG 0x80 -#define I2O_SCSI_DISABLE_SYNC_NEGOTIATION 0x00 -#define I2O_SCSI_ENABLE_SYNC_NEGOTIATION 0x80 - -/* - * - 0001h - SCSI Device Bus Port Info Parameters Group defines - */ - -/* - * Physical - */ - -#define I2O_SCSI_PORT_PHYS_OTHER 0x01 -#define I2O_SCSI_PORT_PHYS_UNKNOWN 0x02 -#define I2O_SCSI_PORT_PHYS_PARALLEL 0x03 -#define I2O_SCSI_PORT_PHYS_FIBRE_CHANNEL 0x04 -#define I2O_SCSI_PORT_PHYS_SERIAL_P1394 0x05 -#define I2O_SCSI_PORT_PHYS_SERIAL_SSA 0x06 - -/* - * Electrical - */ - -#define I2O_SCSI_PORT_ELEC_OTHER 0x01 -#define I2O_SCSI_PORT_ELEC_UNKNOWN 0x02 -#define I2O_SCSI_PORT_ELEC_SINGLE_ENDED 0x03 -#define I2O_SCSI_PORT_ELEC_DIFFERENTIAL 0x04 -#define I2O_SCSI_PORT_ELEC_LOW_VOLT_DIFF 0x05 -#define I2O_SCSI_PORT_ELEC_OPTICAL 0x06 - -/* - * Isochronous - */ - -#define I2O_SCSI_PORT_ISOC_NO 0x00 -#define I2O_SCSI_PORT_ISOC_YES 0x01 -#define I2O_SCSI_PORT_ISOC_UNKNOWN 0x02 - -/* - * Connector Type - */ - -#define I2O_SCSI_PORT_CONN_OTHER 0x01 -#define I2O_SCSI_PORT_CONN_UNKNOWN 0x02 -#define I2O_SCSI_PORT_CONN_NONE 0x03 -#define I2O_SCSI_PORT_CONN_SHIELDED_A_HD 0x04 -#define I2O_SCSI_PORT_CONN_UNSHIELDED_A_HD 0x05 -#define I2O_SCSI_PORT_CONN_SHIELDED_A_LD 0x06 -#define I2O_SCSI_PORT_CONN_UNSHIELDED_A_LD 0x07 -#define I2O_SCSI_PORT_CONN_SHIELDED_P_HD 0x08 -#define I2O_SCSI_PORT_CONN_UNSHIELDED_P_HD 0x09 -#define I2O_SCSI_PORT_CONN_SCA_I 0x0A -#define I2O_SCSI_PORT_CONN_SCA_II 0x0B -#define I2O_SCSI_PORT_CONN_FC_DB9 0x0C -#define I2O_SCSI_PORT_CONN_FC_FIBRE 0x0D -#define I2O_SCSI_PORT_CONN_FC_SCA_II_40 0x0E -#define I2O_SCSI_PORT_CONN_FC_SCA_II_20 0x0F -#define I2O_SCSI_PORT_CONN_FC_BNC 0x10 - -/* - * Connector Gender - */ - -#define I2O_SCSI_PORT_CONN_GENDER_OTHER 0x01 -#define I2O_SCSI_PORT_CONN_GENDER_UNKOWN 0x02 -#define I2O_SCSI_PORT_CONN_GENDER_FEMALE 0x03 -#define I2O_SCSI_PORT_CONN_GENDER_MALE 0x04 - - -/* - * SCSI Device Group 0000h - Device Information Parameter Group - */ - -typedef struct i2o_scsi_device_info_scalar { - uint8_t DeviceType; - uint8_t Flags; - uint16_t Reserved2; - uint32_t Identifier; - uint8_t LunInfo[8]; /* SCSI2 8-bit scalar LUN goes into */ - /* offset 1 */ - uint32_t QueueDepth; - uint8_t Reserved1a; - uint8_t NegOffset; - uint8_t NegDataWidth; - uint8_t Reserved1b; - uint64_t NegSyncRate; -} i2o_scsi_device_info_scalar_t; - -/* - * SCSI Device Group 0001h - Bus Port Information Parameter Group - */ - -typedef struct i2o_scsi_bus_port_info_scalar { - uint8_t PhysicalInterface; - uint8_t ElectricalInterface; - uint8_t Isochronous; - uint8_t ConnectorType; - uint8_t ConnectorGender; - uint8_t Reserved1; - uint16_t Reserved2; - uint32_t MaxNumberDevices; -} i2o_scsi_bus_port_info_scalar_t; - -/* - * I2O SCSI Peripheral Event Indicator Assignment - */ - -#define I2O_SCSI_EVENT_SCSI_SMART 0x00000010 - -/* - * SCSI Peripheral Class Specific Message Definitions - */ - -/* - * I2O SCSI Peripheral Successful Completion Reply Message Frame - */ - -typedef struct i2o_scsi_success_reply_message_frame { - i2o_single_reply_message_frame_t StdReplyFrame; - uint32_t TransferCount; -} i2o_scsi_success_reply_message_frame_t; - - - -/* - * I2O SCSI Peripheral Error Report Reply Message Frame - */ - -#define I2O_SCSI_SENSE_DATA_SZ 40 - -typedef struct i2o_scsi_error_reply_message_frame { - i2o_single_reply_message_frame_t StdReplyFrame; - uint32_t TransferCount; - uint32_t AutoSenseTransferCount; - uint8_t SenseData[I2O_SCSI_SENSE_DATA_SZ]; -} i2o_scsi_error_reply_message_frame_t; - - - -/* - * I2O SCSI Device Reset Message Frame - */ - -typedef struct i2o_scsi_device_reset_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_scsi_device_reset_message_t; - - - -/* - * I2O SCSI Control Block Abort Message Frame - */ - -typedef struct i2o_scsi_scb_abort_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_transaction_context_t TransactionContextToAbort; -} i2o_scsi_scb_abort_message_t; - -/* - * I2O SCSI Control Block Execute Message Frame - */ - -#define I2O_SCSI_CDB_LENGTH 16 - -#define I2O_SCB_FLAG_XFER_DIR_MASK 0xC000 -#define I2O_SCB_FLAG_NO_DATA_XFER 0x0000 -#define I2O_SCB_FLAG_XFER_FROM_DEVICE 0x4000 -#define I2O_SCB_FLAG_XFER_TO_DEVICE 0x8000 - -#define I2O_SCB_FLAG_ENABLE_DISCONNECT 0x2000 - -#define I2O_SCB_FLAG_TAG_TYPE_MASK 0x0380 -#define I2O_SCB_FLAG_NO_TAG_QUEUEING 0x0000 -#define I2O_SCB_FLAG_SIMPLE_QUEUE_TAG 0x0080 -#define I2O_SCB_FLAG_HEAD_QUEUE_TAG 0x0100 -#define I2O_SCB_FLAG_ORDERED_QUEUE_TAG 0x0180 -#define I2O_SCB_FLAG_ACA_QUEUE_TAG 0x0200 - -#define I2O_SCB_FLAG_AUTOSENSE_MASK 0x0060 -#define I2O_SCB_FLAG_DISABLE_AUTOSENSE 0x0000 -#define I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE 0x0020 -#define I2O_SCB_FLAG_SENSE_DATA_IN_BUFFER 0x0060 - -typedef struct i2o_scsi_scb_execute_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint8_t CDBLength; - uint8_t Reserved; - uint16_t SCBFlags; - uint8_t CDB[I2O_SCSI_CDB_LENGTH]; - uint32_t ByteCount; - i2o_sg_element_t SGL; -} i2o_scsi_scb_execute_message_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_I2OBSCSI_H */ diff --git a/usr/src/uts/common/sys/i2o/i2oexec.h b/usr/src/uts/common/sys/i2o/i2oexec.h deleted file mode 100644 index 9dfb92dba2..0000000000 --- a/usr/src/uts/common/sys/i2o/i2oexec.h +++ /dev/null @@ -1,2478 +0,0 @@ -/* - * ***************************************************************************** - * - * All software on this website is made available under the following terms and - * conditions. By downloading this software, you agree to abide by these terms - * and conditions with respect to this software. - * - * I2O SIG All rights reserved. - * - * These header files are provided, pursuant to your I2O SIG membership - * agreement, free of charge on an as-is basis without warranty of any kind, - * either express or implied, including but not limited to, implied warranties - * or merchantability and fitness for a particular purpose. I2O SIG does not - * warrant that this program will meet the user's requirements or that the - * operation of these programs will be uninterrupted or error-free. - * Acceptance and use of this program constitutes the user's understanding - * that he will have no recourse to I2O SIG for any actual or consequential - * damages including, but not limited to, loss profits arising out of use - * or inability to use this program. - * - * Member is permitted to create derivative works to this header-file program. - * However, all copies of the program and its derivative works must contain the - * I2O SIG copyright notice. - * - * ***************************************************************************** - */ - -/* - * ******************************************************************** - * I2OExec.h -- I2O Executive Class Message definition file - * - * This file contains information presented in Chapter 4 of the I2O(tm) - * Specification. - * ******************************************************************** - */ - -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_I2OEXEC_H -#define _SYS_I2OEXEC_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/i2o/i2omsg.h> /* the Base Message file */ -#include <sys/i2o/i2outil.h> -#include <sys/types.h> - - -#define I2OEXEC_REV 1_5_4 /* I2OExec header file revision string */ - - -/* - * **************************************************************************** - * NOTES: - * - * Gets, reads, receives, etc. are all even numbered functions. - * Sets, writes, sends, etc. are all odd numbered functions. - * Functions that both send and receive data can be either but an attempt - * is made to use the function number that indicates the greater transfer - * amount. Functions that do not send or receive data use odd function - * numbers. - * - * Some functions are synonyms like read, receive and send, write. - * - * All common functions will have a code of less than 0x80. - * Unique functions to a class will start at 0x80. - * Executive Functions start at 0xA0. - * - * Utility Message function codes range from 0 - 0x1f - * Base Message function codes range from 0x20 - 0xfe - * Private Message function code is 0xff. - * ***************************************************************************** - */ - -/* I2O Executive Function Codes. */ - -#define I2O_EXEC_ADAPTER_ASSIGN 0xB3 -#define I2O_EXEC_ADAPTER_READ 0xB2 -#define I2O_EXEC_ADAPTER_RELEASE 0xB5 -#define I2O_EXEC_BIOS_INFO_SET 0xA5 -#define I2O_EXEC_BOOT_DEVICE_SET 0xA7 -#define I2O_EXEC_CONFIG_VALIDATE 0xBB -#define I2O_EXEC_CONN_SETUP 0xCA -#define I2O_EXEC_DDM_DESTROY 0xB1 -#define I2O_EXEC_DDM_ENABLE 0xD5 -#define I2O_EXEC_DDM_QUIESCE 0xC7 -#define I2O_EXEC_DDM_RESET 0xD9 -#define I2O_EXEC_DDM_SUSPEND 0xAF -#define I2O_EXEC_DEVICE_ASSIGN 0xB7 -#define I2O_EXEC_DEVICE_RELEASE 0xB9 -#define I2O_EXEC_HRT_GET 0xA8 -#define I2O_EXEC_IOP_CLEAR 0xBE -#define I2O_EXEC_IOP_CONNECT 0xC9 -#define I2O_EXEC_IOP_RESET 0xBD -#define I2O_EXEC_LCT_NOTIFY 0xA2 -#define I2O_EXEC_OUTBOUND_INIT 0xA1 -#define I2O_EXEC_PATH_ENABLE 0xD3 -#define I2O_EXEC_PATH_QUIESCE 0xC5 -#define I2O_EXEC_PATH_RESET 0xD7 -#define I2O_EXEC_STATIC_MF_CREATE 0xDD -#define I2O_EXEC_STATIC_MF_RELEASE 0xDF -#define I2O_EXEC_STATUS_GET 0xA0 -#define I2O_EXEC_SW_DOWNLOAD 0xA9 -#define I2O_EXEC_SW_UPLOAD 0xAB -#define I2O_EXEC_SW_REMOVE 0xAD -#define I2O_EXEC_SYS_ENABLE 0xD1 -#define I2O_EXEC_SYS_MODIFY 0xC1 -#define I2O_EXEC_SYS_QUIESCE 0xC3 -#define I2O_EXEC_SYS_TAB_SET 0xA3 - - -/* I2O Get Status State values */ - -#define I2O_IOP_STATE_INITIALIZING 0x01 -#define I2O_IOP_STATE_RESET 0x02 -#define I2O_IOP_STATE_HOLD 0x04 -#define I2O_IOP_STATE_READY 0x05 -#define I2O_IOP_STATE_OPERATIONAL 0x08 -#define I2O_IOP_STATE_FAILED 0x10 -#define I2O_IOP_STATE_FAULTED 0x11 - - -/* Event Indicator Assignments for the Executive Class. */ - -#define I2O_EVENT_IND_RESOURCE_LIMIT 0x00000001 -#define I2O_EVENT_IND_CONNECTION_FAIL 0x00000002 -#define I2O_EVENT_IND_ADAPTER_FAULT 0x00000004 -#define I2O_EVENT_IND_POWER_FAIL 0x00000008 -#define I2O_EVENT_IND_RESET_PENDING 0x00000010 -#define I2O_EVENT_IND_RESET_IMMINENT 0x00000020 -#define I2O_EVENT_IND_HARDWARE_FAIL 0x00000040 -#define I2O_EVENT_IND_XCT_CHANGE 0x00000080 -#define I2O_EVENT_IND_NEW_LCT_ENTRY 0x00000100 -#define I2O_EVENT_IND_MODIFIED_LCT 0x00000200 -#define I2O_EVENT_IND_DDM_AVAILABILITY 0x00000400 - -/* Resource Limit Event Data */ - -#define I2O_EVENT_RESOURCE_LIMIT_LOW_MEMORY 0x00000001 -#define I2O_EVENT_RESOURCE_LIMIT_INBOUND_POOL_LOW 0x00000002 -#define I2O_EVENT_RESOURCE_LIMIT_OUTBOUND_POOL_LOW 0x00000004 - -/* Connection Fail Event Data */ - -#define I2O_EVENT_CONNECTION_FAIL_REPOND_NORMAL 0x00000000 -#define I2O_EVENT_CONNECTION_FAIL_NOT_REPONDING 0x00000001 -#define I2O_EVENT_CONNECTION_FAIL_NO_AVAILABLE_FRAMES 0x00000002 - -/* Reset Pending Event Data */ - -#define I2O_EVENT_RESET_PENDING_POWER_LOSS 0x00000001 -#define I2O_EVENT_RESET_PENDING_CODE_VIOLATION 0x00000002 - -/* Reset Imminent Event Data */ - -#define I2O_EVENT_RESET_IMMINENT_UNKNOWN_CAUSE 0x00000000 -#define I2O_EVENT_RESET_IMMINENT_POWER_LOSS 0x00000001 -#define I2O_EVENT_RESET_IMMINENT_CODE_VIOLATION 0x00000002 -#define I2O_EVENT_RESET_IMMINENT_PARITY_ERROR 0x00000003 -#define I2O_EVENT_RESET_IMMINENT_CODE_EXCEPTION 0x00000004 -#define I2O_EVENT_RESET_IMMINENT_WATCHDOG_TIMEOUT 0x00000005 - -/* Hardware Fail Event Data */ - -#define I2O_EVENT_HARDWARE_FAIL_UNKNOWN_CAUSE 0x00000000 -#define I2O_EVENT_HARDWARE_FAIL_CPU_FAILURE 0x00000001 -#define I2O_EVENT_HARDWARE_FAIL_MEMORY_FAULT 0x00000002 -#define I2O_EVENT_HARDWARE_FAIL_DMA_FAILURE 0x00000003 -#define I2O_EVENT_HARDWARE_FAIL_IO_BUS_FAILURE 0x00000004 - -/* DDM Availability Event Data */ - -#define I2O_EVENT_DDM_AVAILIBILITY_RESPOND_NORMAL 0x00000000 -#define I2O_EVENT_DDM_AVAILIBILITY_CONGESTED 0x00000001 -#define I2O_EVENT_DDM_AVAILIBILITY_NOT_RESPONDING 0x00000002 -#define I2O_EVENT_DDM_AVAILIBILITY_PROTECTION_VIOLATION 0x00000003 -#define I2O_EVENT_DDM_AVAILIBILITY_CODE_VIOLATION 0x00000004 - - -#define I2O_OPERATION_FLAG_ASSIGN_PERMANENT 0x01 - -/* ExecAdapterAssign Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_adapter_assign_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t DdmTID:12; - uint32_t reserved:12; - uint32_t OperationFlags:8; - } s; - uint32_t w; - } u1; - i2o_hrt_entry_t HRTEntry; -} i2o_exec_adappter_assign_message_t; - -/* macros to access the bit fields in exec adapter assign message */ - -#define get_i2o_exec_adapter_DdmTID(mp, hdl) \ - (mp)->u1.s.DdmTID -#define put_i2o_exec_adapter_DdmTID(mp, id, hdl) \ - ((mp)->u1.s.DdmTID = (id)) -#define get_i2o_exec_adapter_OperationFlags(mp, hdl) \ - (mp)->u1.s.OperationFlags -#define put_i2o_exec_adapter_OperationFlags(mp, n, hdl) \ - ((mp)->u1.s.OperationFlags = (n)) - -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_adapter_assign_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t OperationFlags:8; - uint32_t reserved:12; - uint32_t DdmTID:12; - } s; - uint32_t w; - } u1; - i2o_hrt_entry_t HRTEntry; -} i2o_exec_adappter_assign_message_t; - -/* macros to access the bit fields in exec adapter assign message */ - - -#define get_i2o_exec_adapter_OperationFlags(mp, hdl) \ - (mp)->u1.s.OperationFlags -#define put_i2o_exec_adapter_OperatonFlags(mp, n, hdl) \ - ((mp)->u1.s.OperationFlags = (n)) - -#define get_i2o_exec_adapter_DdmTID(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u1.w) & 0xFFF) -#define put_i2o_exec_adapter_DdmTID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u1.w, \ - (ddi_get32(hdl, &(mp)->u1.w) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - -#define I2O_REQUEST_FLAG_CONFIG_REGISTER 0x00000000 -#define I2O_REQUEST_FLAG_IO_REGISTER 0x00000001 -#define I2O_REQUEST_FLAG_ADAPTER_MEMORY 0x00000002 - -/* ExecAdapterRead Function Message Frame structure. */ - -typedef struct i2o_exec_adapter_read_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t AdapterID; - uint32_t RequestFlags; - uint32_t Offset; - uint32_t Length; - i2o_sg_element_t SGL; -} i2o_exec_adapter_read_message_t; - - -#define I2O_OPERATION_FLAG_RELEASE_PERMANENT 0x01 - -/* ExecAdapterRelease Function Message Frame structure. */ - -typedef struct i2o_exec_dapater_release_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint8_t reserved[3]; - uint8_t OperationFlags; - i2o_hrt_entry_t HRTEntry; -} i2o_exec_adapter_release_message_t; - - - -/* ExecBiosInfoSet Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_bios_info_set_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t DeviceTID:12; - uint32_t reserved:12; - uint32_t BiosInfo:8; - } s; - uint32_t w; - } u1; -} i2o_exec_bios_info_set_message_t; - -/* macros to access the bit fields in exec bios info set message structure */ - -#define get_i2o_exec_bios_DeviceTID(mp, hdl) \ - (mp)->u1.s.DeviceTID -#define put_i2o_exec_bios_DeviceTID(mp, id, hdl) \ - ((mp)->u1.s.DeviceTID = (id)) -#define get_i2o_exec_BiosInfo(mp, hdl) \ - (mp)->u1.s.BiosInfo -#define put_i2o_exec_BiosInfo(mp, n, hdl) \ - ((mp)->u1.s.BiosInfo = (id)) -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_bios_info_set_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t BiosInfo:8; - uint32_t reserved:12; - uint32_t DeviceTID:12; - } s; - uint32_t w; - } u1; -} i2o_exec_bios_info_set_message_t; - -/* macros to access the bit fields in exec bios info set message structure */ - -#define get_i2o_exec_BiosInfo(mp, hdl) \ - (mp)->u1.s.BiosInfo -#define put_i2o_exec_BiosInfo(mp, n, hdl) \ - ((mp)->u1.s.BiosInfo = (n)) - -#define get_i2o_exec_bios_DeviceID(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u1.w) & 0xFFF) -#define put_i2o_exec_bios_DeviceID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u1.w, \ - (ddi_get32(hdl, &(mp)->u1.w) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -/* ExecBootDeviceSet Function Message Frame structure. */ - -typedef struct i2o_exec_boot_device_set_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t BootDevice:12; - uint32_t reserved:20; - } s; - uint32_t w; - } u1; -} i2o_exec_boot_device_set_message_t; - -/* macros to access the bit fields in exec boot set message structure */ - -#define get_i2o_exec_boot_BootDevice(mp, hdl) \ - (mp)->u1.s.BootDevice -#define put_i2o_exec_boot_BootDevice(mp, id, hdl) \ - ((mp)->u1.s.BootDevice = (id)) - -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_boot_device_set_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t reserved:20; - uint32_t BootDevice:12; - } s; - uint32_t w; - } u1; -} i2o_exec_boot_device_set_message_t; - -#define get_i2o_exec_boot_BootDevice(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u1.w) & 0xFFF) -#define put_i2o_exec_boot_BootDevice(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u1.w, \ - (ddi_get32(hdl, &(mp)->u1.w) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -/* ExecConfigValidate Function Message Frame structure. */ - -typedef struct i2o_exec_config_validate_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_exec_config_validate_message_t; - - - -/* ExecConnSetup Requestor */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_alias_connect_setup { - union { - struct { - uint32_t IOP1AliasForTargetDevice:12; - uint32_t IOP2AliasForInitiatorDevice:12; - uint32_t reserved:8; - } s; - uint32_t w; - } u1; -} i2o_alias_connect_setup_t; - -/* macros to access the bit fields in alias connect setup structure */ - -#define get_i2o_exec_setup_IOP1AliasForTargetDevice(mp, hdl) \ - (mp)->u1.s.IOP1AliasForTargetDevice -#define put_i2o_exec_setup_IOP1AliasForTargetDevice(mp, id, hdl) \ - ((mp)->u1.s.IOP1AliasForTargetDevice = (id)) -#define get_i2o_exec_setup_IOP2AliasForInitiatorDevice(mp, hdl) \ - (mp)->u1.s.IOP2AliasForInitiatorDevice -#define put_i2o_exec_setup_IOP2AliasForInitiatortDevice(mp, n, hdl) \ - ((mp)->u1.s.IOP2AliasForInitiatortDevice = (id)) -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_alias_connect_setup { - union { - struct { - uint32_t reserved:8; - uint32_t IOP2AliasForInitiatorDevice:12; - uint32_t IOP1AliasForTargetDevice:12; - } s; - uint32_t w; - } u1; -} i2o_alias_connect_setup_t; - -/* macros to access the bit fields in alias connect setup structure */ - -#define get_i2o_exec_setup_IOP2ForInitiatorDevice(mp, hdl) \ - ((ddi_get32(hdl, &(mp)->u1.w) >> 12) & 0xFFF) -#define put_i2o_exec_setup_IOP2ForInitiatorDevice(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u1.w, (ddi_get32(hdl, &(mp)->u.w) & \ - ~0xFFF000) | (((id) & 0xFFF) << 12)) - -#define get_i2o_exec_setup_IOP1AliasForTargetDevice(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u1.w) & 0xFFF) -#define put_i2o_exec_setup_IOP1AliasForTargetDevice(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u1.w, \ - (ddi_get32(hdl, &(mp)->u1.w) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -#define I2O_OPERATION_FLAG_PEER_TO_PEER_BIDIRECTIONAL 0x01 - -/* ExecConnSetup Object */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_object_connect_setup { - union { - struct { - uint32_t TargetDevice:12; - uint32_t InitiatorDevice:12; - uint32_t OperationFlags:8; - } s; - uint32_t w; - } u1; -} i2o_object_connect_setup_t; - -/* macros to access the bit fields in object connect setup structure */ - -#define get_i2o_exec_setup_TargetDevice(mp, hdl) \ - (mp)->u1.s.TargetDevice -#define put_i2o_exec_setup_TargetDevice(mp, id, hdl) \ - ((mp)->u1.s.TargetDevice = (id)) -#define get_i2o_exec_setup_InitiatorDevice(mp, hdl) \ - (mp)->u1.s.InitiatorDevice -#define put_i2o_exec_setup_InitiatorDevice(mp, n, hdl) \ - ((mp)->u1.s.InitiatorDevice = (id)) -#define get_i2o_exec_setup_OperationFlags(mp, hdl) \ - (mp)->u1.s.OpetationFlags -#define put_i2o_exec_setup_OperationFlags(mp, id, hdl) \ - ((mp)->u1.s.OperationFlags = (id)) -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_object_connect_setup { - union { - struct { - uint32_t OperationFlags:8; - uint32_t InitiatorDevice:12; - uint32_t TargetDevice:12; - } s; - uint32_t w; - } u1; -} i2o_object_connect_setup_t; - -/* macros to access the bit fields in object connect setup structure */ - -#define get_i2o_exec_setup_OperationFlags(mp, hdl) \ - (mp)->u1.s.OperationFlags -#define put_i2o_exec_setup_OperationFlags(mp, n, hdl) \ - ((mp)->u1.s.OperationFlags = (n)) - -#define get_i2o_exec_setup_InitiatorDevice(mp, hdl) \ - ((ddi_get32(hdl, &(mp)->u1.w) >> 12) & 0xFFF) -#define put_i2o_exec_setup_InitiatorDevice(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u1.w, (ddi_get32(hdl, &(mp)->u.w) & \ - ~0xFFF000) | (((id) & 0xFFF) << 12)) - -#define get_i2o_exec_setup_TargetDevice(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u1.w) & 0xFFF) -#define put_i2o_exec_setup_TargetDevice(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u1.w, \ - (ddi_get32(hdl, &(mp)->u1.w) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -/* ExecConnSetup Function Message Frame structure. */ - -typedef struct i2o_exec_conn_setup_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_object_connect_setup_t ObjectInfo; - i2o_alias_connect_setup_t AliasInfo; - uint16_t IOP2InboundMFrameSize; - uint16_t reserved; - uint32_t MessageClass; -} i2o_exec_conn_setup_message_t; - - -/* ExecConnSetup Object Reply */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_object_connect_reply { - union { - struct { - uint32_t TargetDevice:12; - uint32_t InitiatorDevice:12; - uint32_t ReplyStatusCode:8; - } s; - uint32_t w; - } u1; -} i2o_object_connect_reply_t; - -/* macros to access the bit fields in object connect reply structure */ - -#define get_connect_reply_TargetDevice(mp, hdl) \ - (mp)->u1.s.TargetDevice -#define get_connect_reply_InitiatorDevice(mp, hdl) \ - (mp)->u1.s.InitiatorDevice -#define get_connect_reply_RepluStatus(mp, hdl) \ - (mp)->u1.s.ReplyStatusCode - -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_object_connect_reply { - union { - struct { - uint32_t ReplyStatusCode:8; - uint32_t InitiatorDevice:12; - uint32_t TargetDevice:12; - } s; - uint32_t w; - } u1; -} i2o_object_connect_reply_t; - -/* macros to access the bit fields in object connect reply structure */ - -#define get_connect_reply_ReplyStatusCode(mp, hdl) \ - (mp)->u1.s.ReplyStatusCode - -#define get_connect_reply_InitiatorDevice(mp, hdl) \ - ((ddi_get32(hdl, &(mp)->u1.w) >> 12) & 0xFFF) - -#define get_connect_reply_TargetDevice(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u1.w) & 0xFFF) - -#endif - - -/* ExecConnSetup reply structure. */ - -typedef struct i2o_exec_conn_setup_reply { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_object_connect_reply_t ObjectInfo; - i2o_alias_connect_setup_t AliasInfo; - uint16_t IOP2InboundMFrameSize; - uint16_t reserved; -} i2o_exec_conn_setup_reply_t; - - -/* ExecDdmDestroy Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_ddm_destroy_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t DdmTID:12; - uint32_t reserved:20; - } s; - uint32_t w; - } u1; -} i2o_exec_ddm_destroy_message_t; - -/* macros to access the bit fields in exec ddm destroy message structure */ - -#define get_i2o_exec_ddm_destroy_DdmTID(mp, hdl) \ - (mp)->u1.s.DdmTID -#define put_i2o_exec_ddm_destroy_DdmTID(mp, id, hdl) \ - ((mp)->u1.s.DdmTID = (id)) - -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_ddm_destroy_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t reserved:20; - uint32_t DdmTID:12; - } s; - uint32_t w; - } u1; -} i2o_exec_ddm_destroy_message_t; - -/* macros to access the bit fields in exec ddm destroy message structure */ - -#define get_i2o_exec_ddm_destroy_DdmTID(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u1.w) & 0xFFF) -#define put_i2o_exec_ddm_destroy_DdmTID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u1.w, \ - (ddi_get32(hdl, &(mp)->u1.w) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -/* ExecDdmEnable Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_ddm_enable_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t DeviceTID:12; - uint32_t reserved1:20; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t IOP_ID:12; - uint16_t reserved:4; - } s3; - uint16_t h1; - } u3; - uint16_t HostUnitID; -} i2o_exec_ddm_enable_message_t; - -/* macros to access the bit fields in exec ddm enable message structure */ - -#define get_i2o_exec_ddm_enable_DeviceTID(mp, hdl) \ - (mp)->u2.s2.DeviceTID -#define put_i2o_exec_ddm_enable_DeviceTID(mp, id, hdl) \ - ((mp)->u2.s2.DeviceTID = (id)) - -#define get_i2o_exec_ddm_enable_IOP_ID(mp, hdl) \ - (mp)->u3.s3.IOP_ID -#define put_i2o_exec_ddm_enable_IOP_ID(mp, id, hdl) \ - ((mp)->u3.s3.IOP_ID = (id)) - -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_ddm_enable_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t reserved1:20; - uint32_t DeviceTID:12; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t reserved:4; - uint16_t IOP_ID:12; - } s3; - uint16_t h1; - } u3; - uint16_t HostUnitID; -} i2o_exec_ddm_enable_message_t; - -/* macros to access the bit fields in exec ddm enable message structure */ - -#define get_i2o_exec_ddm_enable_DeviceTID(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u2.w2) & 0xFFF) -#define put_i2o_exec_ddm_enable_DeviceTID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, \ - (ddi_get32(hdl, &(mp)->u2.w2) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_i2o_exec_ddm_enable_IOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u3.h1) & 0xFFF) - -#define put_i2o_exec_ddm_enable_IOP_ID(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u3.h1, \ - (ddi_get16(hdl, &(mp)->u3.h1) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - -/* ExecDdmQuiesce Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_ddm_quiesce_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t DeviceTID:12; - uint32_t reserved1:20; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t IOP_ID:12; - uint16_t reserved:4; - } s3; - uint16_t h1; - } u3; - uint16_t HostUnitID; -} i2o_exec_ddm_quiesce_message_t; - -/* macros to access the bit fields in exec ddm quiesce message structure */ - -#define get_i2o_exec_ddm_quiesce_DeviceTID(mp, hdl) \ - (mp)->u2.s2.DeviceTID -#define put_i2o_exec_ddm_quiesce_DeviceTID(mp, id, hdl) \ - ((mp)->u2.s2.DeviceTID = (id)) - -#define get_i2o_exec_ddm_quiesce_IOP_ID(mp, hdl) \ - (mp)->u3.s3.IOP_ID -#define put_i2o_exec_ddm_quiesce_IOP_ID(mp, id, hdl) \ - ((mp)->u3.s3.IOP_ID = (id)) - -#endif - - -/* ExecDdmQuiesce Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_ddm_quiesce_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t reserved1:20; - uint32_t DeviceTID:12; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t reserved:4; - uint16_t IOP_ID:12; - } s3; - uint16_t h1; - } u3; - uint16_t HostUnitID; -} i2o_exec_ddm_quiesce_message_t; - -/* macros to access the bit fields in exec ddm quiesce message structure */ - -#define get_i2o_exec_ddm_quiesce_DeviceTID(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u2.w2) & 0xFFF) -#define put_i2o_exec_ddm_quiesce_DeviceTID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, \ - (ddi_get32(hdl, &(mp)->u2.w2) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_i2o_exec_ddm_quiesce_IOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u3.h1) & 0xFFF) - -#define put_i2o_exec_ddm_quiesce_IOP_ID(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u3.h1, \ - (ddi_get16(hdl, &(mp)->u3.h1) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -/* ExecDdmReset Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_ddm_reset_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t DeviceTID:12; - uint32_t reserved1:20; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t IOP_ID:12; - uint16_t reserved:4; - } s3; - uint16_t h1; - } u3; - uint16_t HostUnitID; -} i2o_exec_ddm_reset_message_t; - -/* macros to access the bit fields in exec ddm reset message structure */ - -#define get_i2o_exec_ddm_reset_DeviceTID(mp, hdl) \ - (mp)->u2.s2.DeviceTID -#define put_i2o_exec_ddm_reset_DeviceTID(mp, id, hdl) \ - ((mp)->u2.s2.DeviceTID = (id)) - -#define get_i2o_exec_ddm_reset_IOP_ID(mp, hdl) \ - (mp)->u3.s3.IOP_ID -#define put_i2o_exec_ddm_resetquiesce_IOP_ID(mp, id, hdl) \ - ((mp)->u3.s3.IOP_ID = (id)) - -#endif - - -/* ExecDdmReset Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_ddm_reset_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t reserved1:20; - uint32_t DeviceTID:12; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t reserved:4; - uint16_t IOP_ID:12; - } s3; - uint16_t h1; - } u3; - uint16_t HostUnitID; -} i2o_exec_ddm_reset_message_t; - -/* macros to access the bit fields in exec ddm reset message structure */ - -#define get_i2o_exec_ddm_reset_DeviceTID(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u2.w2) & 0xFFF) -#define put_i2o_exec_ddm_reset_DeviceTID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, \ - (ddi_get32(hdl, &(mp)->u2.w2) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_i2o_exec_ddm_reset_IOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u3.h1) & 0xFFF) - -#define put_i2o_exec_ddm_reset_IOP_ID(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u3.h1, \ - (ddi_get16(hdl, &(mp)->u3.h1) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -/* ExecDdmSuspend Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_ddm_suspend_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t DdmTID:12; - uint32_t reserved:20; - } s; - uint32_t w; - } u1; -} i2o_exec_ddm_suspend_message_t; - -/* macros to access the bit fields in exec ddm suspend message structure */ - -#define get_i2o_exec_ddm_suspend_DdmTID(mp, hdl) \ - (mp)->u1.s.DdmTID -#define put_i2o_exec_ddm_suspend_DdmTID(mp, id, hdl) \ - ((mp)->u1.s.DdmTID = (id)) - -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_ddm_suspend_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t reserved:20; - uint32_t DdmTID:12; - } s; - uint32_t w; - } u1; -} i2o_exec_ddm_suspend_message_t; - -/* macros to access the bit fields in exec ddm suspend message structure */ - -#define get_i2o_exec_ddm_suspend_DdmTID(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u1.w) & 0xFFF) -#define put_i2o_exec_ddm_suspend_DdmTID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u1.w, \ - (ddi_get32(hdl, &(mp)->u1.w) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -#define I2O_OPERATION_FLAG_ASSIGN_PERMANENT 0x01 - - -/* ExecDeviceAssign Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_device_assign_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t DeviceTID:12; - uint32_t DdmTID:12; - uint32_t OperationFlags:8; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t IOP_ID:12; - uint16_t reserved:4; - } s3; - uint16_t h1; - } u3; - uint16_t HostUnitID; -} i2o_exec_device_assign_message_t; - - -/* macros to access the bit fields in device assign message structure */ - -#define get_i2o_exec_device_assign_DeviceTID(mp, hdl) \ - (mp)->u2.s2.DeviceTID -#define put_i2o_exec_device_assign_DeviceTID(mp, id, hdl) \ - ((mp)->u2.s2.DeviceTID = (id)) -#define get_i2o_exec_device_assign_DdmTID(mp, hdl) \ - (mp)->u2.s2.DdmTID -#define put_i2o_exec_device_assign_DdmTID(mp, n, hdl) \ - ((mp)->u2.s2.DdmTID = (id)) -#define get_i2o_exec_device_assign_OperationFlags(mp, hdl) \ - (mp)->u2.s2.OpetationFlags -#define put_i2o_exec_device_assign_OperationFlags(mp, id, hdl) \ - ((mp)->u2.s2.OperationFlags = (id)) - -#define get_i2o_exec_device_assign_IOP_ID(mp, hdl) \ - (mp)->u3.s3.IOP_ID -#define put_i2o_exec_device_assign_IOP_ID(mp, id, hdl) \ - ((mp)->u3.s3.IOP_ID = (id)) -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - - -typedef struct i2o_exec_device_assign_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t OperationFlags:8; - uint32_t DdmTID:12; - uint32_t DeviceTID:12; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t reserved:4; - uint16_t IOP_ID:12; - } s3; - uint16_t h1; - } u3; - uint16_t HostUnitID; -} i2o_exec_device_assign_message_t; - -/* macros to access the bit fields in device assign message structure */ - -#define get_i2o_exec_device_assign_OperationFlags(mp, hdl) \ - (mp)->u2.s2.OperationFlags -#define put_i2o_exec_device_assign_OperationFlags(mp, n, hdl) \ - ((mp)->u2.s2.OperationFlags = (n)) - -#define get_i2o_exec_device_assign_DdmTID(mp, hdl) \ - ((ddi_get32(hdl, &(mp)->u2.w2) >> 12) & 0xFFF) -#define put_i2o_exec_device_assign_DdmTID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, (ddi_get32(hdl, &(mp)->u2.w2) & \ - ~0xFFF000) | (((id) & 0xFFF) << 12)) - -#define get_i2o_exec_device_assign_DeviceTID(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u2.w2) & 0xFFF) -#define put_i2o_exec_device_assign_DeviceTID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, \ - (ddi_get32(hdl, &(mp)->u2.w2) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_i2o_exec_device_assign_IOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u3.h1) & 0xFFF) -#define put_i2o_exec_device_assign_IOP_ID(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u3.h1, \ - (ddi_get16(hdl, &(mp)->u3.h1) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -#define I2O_OPERATION_FLAG_RELEASE_PERMANENT 0x01 - -/* ExecDeviceRelease Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_device_release_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t DeviceTID:12; - uint32_t DdmTID:12; - uint32_t OperationFlags:8; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t IOP_ID:12; - uint16_t reserved:4; - } s3; - uint16_t h1; - } u3; - uint16_t HostUnitID; -} i2o_exec_device_release_message_t; - - -/* macros to access the bit fields in device release message structure */ - -#define get_i2o_exec_device_release_DeviceTID(mp, hdl) \ - (mp)->u2.s2.DeviceTID -#define put_i2o_exec_device_release_DeviceTID(mp, id, hdl) \ - ((mp)->u2.s2.DeviceTID = (id)) -#define get_i2o_exec_device_release_DdmTID(mp, hdl) \ - (mp)->u2.s2.DdmTID -#define put_i2o_exec_device_release_DdmTID(mp, n, hdl) \ - ((mp)->u2.s2.DdmTID = (id)) -#define get_i2o_exec_device_release_OperationFlags(mp, hdl) \ - (mp)->u2.s2.OpetationFlags -#define put_i2o_exec_device_release_OperationFlags(mp, id, hdl) \ - ((mp)->u2.s2.OperationFlags = (id)) - -#define get_i2o_exec_device_release_IOP_ID(mp, hdl) \ - (mp)->u3.s3.IOP_ID -#define put_i2o_exec_device_release_IOP_ID(mp, id, hdl) \ - ((mp)->u3.s3.IOP_ID = (id)) -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - - -typedef struct i2o_exec_device_release_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t OperationFlags:8; - uint32_t DdmTID:12; - uint32_t DeviceTID:12; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t reserved:4; - uint16_t IOP_ID:12; - } s3; - uint16_t h1; - } u3; - uint16_t HostUnitID; -} i2o_exec_device_release_message_t; - -/* macros to access the bit fields in device assign message structure */ - - -#define get_i2o_exec_device_release_OperationFlags(mp, hdl) \ - (mp)->u2.s2.OperationFlags -#define put_i2o_exec_device_release_OperationFlags(mp, n, hdl) \ - ((mp)->u2.s2.OperationFlags = (n)) - -#define get_i2o_exec_device_release_DdmTID(mp, hdl) \ - ((ddi_get32(hdl, &(mp)->u2.w2) >> 12) & 0xFFF) -#define put_i2o_exec_device_release_DdmTID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, (ddi_get32(hdl, &(mp)->u2.w2) & \ - ~0xFFF000) | (((id) & 0xFFF) << 12)) - -#define get_i2o_exec_device_release_DeviceTID(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u2.w2) & 0xFFF) -#define put_i2o_exec_device_release_DeviceTID(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, \ - (ddi_get32(hdl, &(mp)->u2.w2) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_i2o_exec_device_release_IOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u3.h1) & 0xFFF) - -#define put_i2o_exec_device_release_IOP_ID(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u3.h1, \ - (ddi_get16(hdl, &(mp)->u3.h1) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -/* HRT Entry Structure defined in I2OMSG.H */ - -/* ExecHrtGet Function Message Frame structure. */ - -typedef struct i2o_exec_hrt_get_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_sg_element_t SGL; -} i2o_exec_hrt_get_message_t; - - - -/* ExecIopClear Function Message Frame structure. */ - -typedef struct i2o_exec_iop_clear_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_exec_iop_clear_message_t; - - -/* ExecIopConnect Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_iop_connect_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t reserved:24; - uint32_t IOP1MsgerType:8; - - } s2; - uint32_t w2; - } u2; - uint16_t IOP1InboundMFrameSize; - union { - struct { - uint16_t IOP1AliasForIOP2:12; - uint16_t reserved1:4; - } s3; - uint16_t h2; - } u3; - union { - struct { - uint16_t IOP_ID1:12; - uint16_t reserved2:4; - } s4; - uint16_t h1; - } u4; - uint16_t HostUnitID1; -} i2o_exec_iop_connect_message_t; - - -/* macros to access the bit fields in exec iop connect message structure */ - -#define get_i2o_exec_iop_connect_IOP1MsgerType(p, hdl) \ - (mp)->u2.s2.IOP1MsgerType - -#define put_i2o_exec_iop_connect_IOP1MsgerType(mp, id, hdl) \ - ((mp)->u2.s2.IOP1MsgerType = (id)) - - -#define get_i2o_exec_iop_connect_IOP1AliasForIOP2(p, hdl) \ - (mp)->u3.s3.IOP1AliasForIOP2 - -#define put_i2o_exec_iop_connect_IOP1AliasForIOP2(mp, id, hdl) \ - ((mp)->u3.s3.IOP1AliasForIOP2 = (id)) - -#define get_i2o_exec_iop_connect_IOP_ID1(p, hdl) \ - (mp)->u4.s4.IOP_ID1 - -#define put_i2o_exec_iop_connect_IOP_ID1(mp, id, hdl) \ - ((mp)->u4.s4.IOP_ID1 = (id)) - - -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_iop_connect_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint32_t IOP1MsgerType:8; - uint32_t reserved:24; - } s2; - uint32_t w2; - } u2; - - uint16_t IOP1InboundMFrameSize; - union { - struct { - uint16_t reserved1:8; - uint16_t IOP1AliasForIOP2:12; - } s3; - uint16_t h2; - } u3; - union { - struct { - uint16_t reserved2:4; - uint16_t IOP_ID1:12; - } s4; - uint16_t h1; - } u4; - uint16_t HostUnitID1; -} i2o_exec_iop_connect_message_t; - -/* macros to access the bit fields in exec iop connect message structure */ - -#define get_i2o_exec_iop_connect_IOP1MsgerType(p, hdl) \ - ((ddi_get32(hdl, &(p)->u2.w2) >> 24) & 0xFF) - -#define put_i2o_exec_iop_connect_IOP1MsgerType(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, \ - (ddi_get32(hdl, &(mp)->u2.w2) & ~0xFF) | (((id) & 0xFF) << 24)) - - -#define get_i2o_exec_iop_connect_IOP1AliasForIOP2(p, hdl) \ - (ddi_get16(hdl, &(p)->u3.h2) & 0xFFF) - -#define put_i2o_exec_iop_connect_IOP1AliasForIOP2(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u3.h2, \ - (ddi_get16(hdl, &(mp)->u3.h2) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_i2o_exec_iop_connect_IOP_ID1(p, hdl) \ - (ddi_get32(hdl, &(p)->u4.h1) & 0xFFF) - -#define put_i2o_exec_iop_connect_IOP_ID1(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u4.h1, \ - (ddi_get16(hdl, &(mp)->u4.h1) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -/* ExecIopConnect reply structure */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_iop_connect_iop_reply { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t DetailedStatusCode; - uint8_t reserved; - uint8_t ReqStatus; - uint16_t IOP2InboundMFrameSize; - union { - struct { - uint16_t IOP2AliasForIOP1:12; - uint16_t reserved1:4; - } s3; - uint16_t h2; - } u3; - union { - struct { - uint16_t IOP_ID2:12; - uint16_t reserved2:4; - } s4; - uint16_t w4; - } u4; - uint16_t HostUnitID2; -} i2o_exec_iop_connect_reply_t; - -/* macros to access the bit fields in exec iop connect reply structure */ - -#define get_i2o_exec_iop_connect_reply_IOP2AliasForIOP1(p, hdl) \ - (mp)->u3.s3.IOP2AliasForIOP1 - -#define put_i2o_exec_iop_connect_reply_IOP2AliasForIOP1(mp, id, hdl) \ - ((mp)->u3.s3.IOP2AliasForIOP1 = (id)) - -#define get_i2o_exec_iop_connect_reply_IOP_ID2(p, hdl) \ - (mp)->u4.s4.IOP_ID2 - -#define put_i2o_exec_iop_connect_reply_IOP_ID2(mp, id, hdl) \ - ((mp)->u4.s4.IOP_ID2 = (id)) - -#endif - - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_iop_connect_iop_reply { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t DetailedStatusCode; - uint8_t reserved; - uint8_t ReqStatus; - uint16_t IOP2InboundMFrameSize; - union { - struct { - uint16_t reserved1:8; - uint16_t IOP2AliasForIOP1:12; - } s3; - uint16_t h2; - } u3; - union { - struct { - uint16_t reserved2:4; - uint16_t IOP_ID2:12; - } s4; - uint16_t h1; - } u4; - uint16_t HostUnitID2; -} i2o_exec_iop_connect_reply_t; - -/* macros to access the bit fields in exec iop connect reply structure */ - -#define get_i2o_exec_iop_connect_reply_IOP2AliasForIOP1(p, hdl) \ - (ddi_get16(hdl, &(p)->u3.h2) & 0xFFF) - -#define put_i2o_exec_iop_connect_reply_IOP2AliasForIOP1(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u3.h2, \ - (ddi_get16(hdl, &(mp)->u3.h2) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_i2o_exec_iop_connect_reply_IOP_ID2(p, hdl) \ - (ddi_get32(hdl, &(p)->u4.h1) & 0xFFF) - -#define put_i2o_exec_iop_connect_reply_IOP_ID2(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u4.h1, \ - (ddi_get16(hdl, &(mp)->u4.h1) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -#define I2O_EXEC_IOP_RESET_RESERVED_SZ 16 - -#define I2O_EXEC_IOP_RESET_IN_PROGRESS 0x01 -#define I2O_EXEC_IOP_RESET_REJECTED 0x02 - -#define I2O_EXEC_IOP_RESET_STATUS_RESERVED_SZ 3 - -typedef struct i2o_exec_iop_reset_status { - volatile uint8_t ResetStatus; - uint8_t reserved[I2O_EXEC_IOP_RESET_STATUS_RESERVED_SZ]; -} i2o_exec_iop_reset_status_t; - - -/* ExecIopReset Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_iop_reset_message { - uint8_t VersionOffset; - uint8_t MsgFlags; - uint16_t MessageSize; - union { - struct { - uint32_t TargetAddress:12; - uint32_t InitiatorAddress:12; - uint32_t Function:8; - } s2; - uint32_t w2; - } u2; - uint8_t Reserved[I2O_EXEC_IOP_RESET_RESERVED_SZ]; - uint32_t StatusWordLowAddress; - uint32_t StatusWordHighAddress; -} i2o_exec_iop_reset_message_t; - -/* macros to access the bit fields in iop reset message */ - -#define get_i2o_exec_reset_TargetAddress(mp, hdl) \ - (mp)->u2.s2.TargetAddress -#define put_i2o_exec_reset_TargetAddress(mp, id, hdl) \ - ((mp)->u2.s2.TargetAddress = (id)) -#define get_i2o_exec_reset_InitiatorAddress(mp, hdl) \ - (mp)->u2.s2.InitiatorAddress -#define put_i2o_exec_reset_InitiatorAddress(mp, id, hdl) \ - ((mp)->u2.s2.InitiatorAddress = (id)) -#define get_i2o_exec_reset_Function(mp, hdl) \ - (mp)->u2.s2.Function -#define put_i2o_exec_reset_Function(mp, n, hdl) \ - ((mp)->u2.s2.Function = (n)) -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_iop_reset_message { - uint8_t VersionOffset; - uint8_t MsgFlags; - uint16_t MessageSize; - union { - struct { - uint32_t Function:8; - uint32_t InitiatorAddress:12; - uint32_t TargetAddress:12; - } s2; - uint32_t w2; - } u2; - - uint8_t Reserved[I2O_EXEC_IOP_RESET_RESERVED_SZ]; - uint32_t StatusWordLowAddress; - uint32_t StatusWordHighAddress; -} i2o_exec_iop_reset_message_t; - -/* macros to access the bit fields in iop reset message */ - -#define get_i2o_exec_reset_Function(mp, hdl) \ - (mp)->u2.s2.Function -#define put_i2o_exec_reset_Function(mp, n, hdl) \ - ((mp)->u2.s2.Function = (n)) - -#define get_i2o_exec_reset_TargetAddress(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u2.w2) & 0xFFF) -#define put_i2o_exec_reset_TargetAddress(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, \ - (ddi_get32(hdl, &(mp)->u2.w2) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_i2o_exec_reset_InitiatorAddress(mp, hdl) \ - ((ddi_get32(hdl, &(mp)->u2.w2) >> 12) & 0xFFF) -#define put_i2o_exec_reset_InitiatorAddress(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, (ddi_get32(hdl, &(mp)->u2.w2) & \ - ~0xFFF000) | (((id) & 0xFFF) << 12)) - -#endif - - -/* LCT Entry Structure defined in I2OMSG.H */ - -/* ExecLCTNotify Function Message Frame structure. */ - -typedef struct i2o_exec_lct_notify_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t ClassIdentifier; - uint32_t LastReportedChangeIndicator; - i2o_sg_element_t SGL; -} i2o_exec_lct_notify_message_t; - - -/* ExecOutboundInit Function Message Frame structure. */ - -typedef struct i2o_exec_outbound_init_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t HostPageFrameSize; - uint8_t InitCode; - uint8_t reserved; - uint16_t OutboundMFrameSize; - i2o_sg_element_t SGL; -} i2o_exec_outbound_init_message_t; - - -#define I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS 0x01 -#define I2O_EXEC_OUTBOUND_INIT_REJECTED 0x02 -#define I2O_EXEC_OUTBOUND_INIT_FAILED 0x03 -#define I2O_EXEC_OUTBOUND_INIT_COMPLETE 0x04 - -#define I2O_EXEC_OUTBOUND_INIT_RESERVED_SZ 3 - - -typedef struct i2o_exec_outbound_init_status { - uint8_t InitStatus; - uint8_t reserved[I2O_EXEC_OUTBOUND_INIT_RESERVED_SZ]; -} i2o_exec_outbound_init_status_t; - - -typedef struct i2o_exec_outbound_init_reclaim_list { - uint32_t MFACount; - uint32_t MFAReleaseCount; - uint32_t MFAAddress[1]; -} i2o_exec_outbound_init_reclaim_list_t; - - -/* ExecPathEnable Function Message Frame structure. */ - - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_path_enable_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint16_t IOP_ID:12; - uint16_t reserved:4; - } s2; - uint16_t h1; - } u2; - uint16_t HostUnitID; -} i2o_exec_path_enable_message_t; - -/* macros to access the bit fields in exec path enable message structure */ - -#define get_i2o_exec_path_enable_IOP_ID(mp, hdl) \ - (mp)->u2.s2.IOP_ID -#define put_i2o_exec_path_enable_IOP_ID(mp, id, hdl) \ - ((mp)->u2.s2.IOP_ID = (id)) -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_path_enable_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint16_t reserved:4; - uint16_t IOP_ID:12; - } s2; - uint16_t h1; - } u2; - uint16_t HostUnitID; -} i2o_exec_path_enable_message_t; - -/* macros to access the bit fields in exec path enable message structure */ - -#define get_i2o_exec_path_enable_IOP_ID(p, hdl) \ - (ddi_get32(hdl, &(p)->u2.h1) & 0xFFF) - -#define put_i2o_exec_path_enable_IOP_ID(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u2.h1, \ - (ddi_get16(hdl, &(mp)->u2.h1) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -/* ExecPathQuiesce Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_path_quiesce_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint16_t IOP_ID:12; - uint16_t reserved:4; - } s2; - uint16_t h1; - } u2; - uint16_t HostUnitID; -} i2o_exec_path_quiesce_message_t; - -/* macros to access the bit fields in exec path quiesce message structure */ - -#define get_i2o_exec_path_quiesce_IOP_ID(mp, hdl) \ - (mp)->u2.s2.IOP_ID -#define put_i2o_exec_path_quiesce_IOP_ID(mp, id, hdl) \ - ((mp)->u2.s2.IOP_ID = (id)) - -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_path_quiesce_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint16_t reserved:4; - uint16_t IOP_ID:12; - } s2; - uint16_t h1; - } u2; - uint16_t HostUnitID; -} i2o_exec_path_quiesce_message_t; - -/* macros to access the bit fields in exec path quiesce message structure */ - -#define get_i2o_exec_path_quiesce_IOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u2.h1) & 0xFFF) - -#define put_i2o_exec_path_quiesce_IOP_ID(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u2.h1, \ - (ddi_get16(hdl, &(mp)->u2.h1) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -/* ExecPathReset Function Message Frame structure. */ - - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_path_reset_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint16_t IOP_ID:12; - uint16_t reserved:4; - } s2; - uint16_t h1; - } u2; - uint16_t HostUnitID; -} i2o_exec_path_reset_message_t; - -/* macros to access the bit fields in exec path reset message structure */ - -#define get_i2o_exec_path_reset_IOP_ID(mp, hdl) \ - (mp)->u2.s2.IOP_ID -#define put_i2o_exec_path_reset_IOP_ID(mp, id, hdl) \ - ((mp)->u2.s2.IOP_ID = (id)) -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_path_reset_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint16_t reserved:4; - uint16_t IOP_ID:12; - } s2; - uint16_t h1; - } u2; - uint16_t HostUnitID; -} i2o_exec_path_reset_message_t; - -/* macros to access the bit fields in exec path reset message structure */ - -#define get_i2o_exec_path_reset_IOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u2.h1) & 0xFFF) - -#define put_i2o_exec_path_reset_IOP_ID(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u2.h1, \ - (ddi_get16(hdl, &(mp)->u2.h1) & ~0xFFF) | ((id) & 0xFFF)) - - -#endif - - -#define I2O_EXEC_STATIC_MF_CREATE_RESERVED_SZ 3 - -/* ExecStaticMfCreate Message Frame structure */ - -typedef struct i2o_exec_static_mf_create_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint8_t MaxOutstanding; - uint8_t reserved[I2O_EXEC_STATIC_MF_CREATE_RESERVED_SZ]; - i2o_message_frame_t StaticMessageFrame; -} i2o_exec_static_mf_create_message_t; - - -/* ExecStaticMfCreate Message Frame reply */ - -typedef struct i2o_exec_static_mf_create_reply { - i2o_single_reply_message_frame_t StdReplyFrame; - i2o_message_frame_t StaticMFA; -} i2o_exec_static_mf_create_reply_t; - - -/* ExecStaticMfRelease Message Frame structure */ - -typedef struct i2o_exec_static_mf_release_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_message_frame_t StaticMFA; -} i2o_exec_static_mf_release_message_t; - - - -#define I2O_EXEC_STATUS_GET_RESERVED_SZ 16 - -/* ExecStatusGet Function Message Frame structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_status_get_message { - uint8_t VersionOffset; - uint8_t MsgFlags; - uint16_t MessageSize; - union { - struct { - uint32_t Function:8; - uint32_t InitiatorAddress:12; - uint32_t TargetAddress:12; - } s2; - uint32_t w2; - } u2; - uint8_t Reserved[I2O_EXEC_STATUS_GET_RESERVED_SZ]; - uint32_t ReplyBufferAddressLow; - uint32_t ReplyBufferAddressHigh; - uint32_t ReplyBufferLength; -} i2o_exec_status_get_message_t; - -/* macros to access the bit fields in i2o exec status get message */ - -#define get_i2o_exec_status_TargetAddress(mp, hdl) \ - (mp)->u2.s2.TargetAddress -#define put_i2o_exec_status_TargetAddress(mp, id, hdl) \ - ((mp)->u2.s2.TargetAddress = (id)) -#define get_i2o_exec_status_InitiatorAddress(mp, hdl) \ - (mp)->u2.s2.InitiatorAddress -#define put_i2o_exec_status_InitiatorAddress(mp, id, hdl) \ - ((mp)->u2.s2.InitiatorAddress = (id)) -#define get_i2o_exec_status_Function(mp, hdl) \ - (mp)->u2.s2.Function -#define put_i2o_exec_status_Function(mp, n, hdl) \ - ((mp)->u2.s2.Function = (n)) - -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_status_get_message { - uint8_t VersionOffset; - uint8_t MsgFlags; - uint16_t MessageSize; - union { - struct { - uint32_t Function:8; - uint32_t InitiatorAddress:12; - uint32_t TargetAddress:12; - } s2; - uint32_t w2; - } u2; - uint8_t Reserved[I2O_EXEC_STATUS_GET_RESERVED_SZ]; - uint32_t ReplyBufferAddressLow; - uint32_t ReplyBufferAddressHigh; - uint32_t ReplyBufferLength; -} i2o_exec_status_get_message_t; - -/* macros to access the bit fields in i2o exec status get message */ - -#define get_i2o_exec_status_Function(mp, hdl) \ - (mp)->u2.s2.Function -#define put_i2o_exec_status_Function(mp, n, hdl) \ - ((mp)->u2.s2.Function = (n)) - -#define get_i2o_exec_status_TargetAddress(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u2.w2) & 0xFFF) -#define put_i2o_exec_status_TargetAddress(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, \ - (ddi_get32(hdl, &(mp)->u2.w2) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_i2o_exec_status_InitiatorAddress(mp, hdl) \ - ((ddi_get32(hdl, &(mp)->u2.w2) >> 12) & 0xFFF) -#define put_i2o_exec_status_InitiatorAddress(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, (ddi_get32(hdl, &(mp)->u2.w2) & \ - ~0xFFF000) | (((id) & 0xFFF) << 12)) - -#endif - - -#define I2O_IOP_STATUS_PROD_ID_STR_SZ 24 -#define I2O_EXEC_STATUS_GET_REPLY_RESERVED_SZ 6 - -/* ExecStatusGet reply Structure */ - -#define I2O_IOP_CAP_CONTEXT_32_ONLY 0x00000000 -#define I2O_IOP_CAP_CONTEXT_64_ONLY 0x00000001 -#define I2O_IOP_CAP_CONTEXT_32_64_NOT_CURRENTLY 0x00000002 -#define I2O_IOP_CAP_CONTEXT_32_64_CURRENTLY 0x00000003 -#define I2O_IOP_CAP_CURRENT_CONTEXT_NOT_CONFIG 0x00000000 -#define I2O_IOP_CAP_CURRENT_CONTEXT_32_ONLY 0x00000004 -#define I2O_IOP_CAP_CURRENT_CONTEXT_64_ONLY 0x00000008 -#define I2O_IOP_CAP_CURRENT_CONTEXT_32_64 0x0000000C -#define I2O_IOP_CAP_INBOUND_PEER_SUPPORT 0x00000010 -#define I2O_IOP_CAP_OUTBOUND_PEER_SUPPORT 0x00000020 -#define I2O_IOP_CAP_PEER_TO_PEER_SUPPORT 0x00000040 - - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_status_get_reply { - uint16_t OrganizationID; - uint16_t reserved; - union { - struct { - uint16_t IOP_ID:12; - uint16_t reserved1:4; - } s2; - uint16_t h1; - } u2; - uint16_t HostUnitID; - union { - struct { - uint16_t SegmentNumber:12; - uint16_t I2oVersion:4; - } s3; - uint16_t h1; - } u3; - uint8_t IopState; - uint8_t MessengerType; - uint16_t InboundMFrameSize; - uint8_t InitCode; - uint8_t reserved2; - uint32_t MaxInboundMFrames; - uint32_t CurrentInboundMFrames; - uint32_t MaxOutboundMFrames; - uint8_t ProductIDString[I2O_IOP_STATUS_PROD_ID_STR_SZ]; - uint32_t ExpectedLCTSize; - uint32_t IopCapabilities; - uint32_t DesiredPrivateMemSize; - uint32_t CurrentPrivateMemSize; - uint32_t CurrentPrivateMemBase; - uint32_t DesiredPrivateIOSize; - uint32_t CurrentPrivateIOSize; - uint32_t CurrentPrivateIOBase; - uint8_t reserved3[3]; - volatile uint8_t SyncByte; -} i2o_exec_status_get_reply_t; - -#define get_i2o_exec_status_reply_IOP_ID(p, hdl) (p)->u2.s2.IOP_ID -#define get_i2o_exec_status_reply_SegmentNumber(p, hdl)(p)->u3.s3.SegmentNumber -#define get_i2o_exec_status_reply_I2oVersion(p, hdl)(p)->u3.s3.I2oVersion - -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_status_get_reply { - uint16_t OrganizationID; - uint16_t reserved; - union { - struct { - uint16_t reserved1:4; - uint16_t IOP_ID:12; - } s2; - uint16_t h1; - } u2; - uint16_t HostUnitID; - union { - struct { - uint16_t I2oVersion:4; - uint16_t SegmentNumber:12; - } s3; - uint16_t h1; - } u3; - uint8_t IopState; - uint8_t MessengerType; - uint16_t InboundMFrameSize; - uint8_t InitCode; - uint8_t reserved2; - uint32_t MaxInboundMFrames; - uint32_t CurrentInboundMFrames; - uint32_t MaxOutboundMFrames; - uint8_t ProductIDString[I2O_IOP_STATUS_PROD_ID_STR_SZ]; - uint32_t ExpectedLCTSize; - uint32_t IopCapabilities; - uint32_t DesiredPrivateMemSize; - uint32_t CurrentPrivateMemSize; - uint32_t CurrentPrivateMemBase; - uint32_t DesiredPrivateIOSize; - uint32_t CurrentPrivateIOSize; - uint32_t CurrentPrivateIOBase; - uint8_t reserved3[3]; - uint8_t SyncByte; -} i2o_exec_status_get_reply_t; - -#define get_i2o_exec_status_reply_IOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u2.h1) & 0xFFF) - -#define get_i2o_exec_status_reply_I2oVersion(p, hdl) \ - (ddi_get16(hdl, &(p)->u3.h1) >> 4) -#define get_i2o_exec_staus_reply_SegmentNumber(p, hdl) \ - (ddi_get16(hdl, &(p)->u3.h1) & 0xFFF) - -#endif - - -#define I2O_EXEC_SW_DOWNLOAD_FLAG_LOAD_MEMORY 0x00 -#define I2O_EXEC_SW_DOWNLOAD_FLAG_PERMANENT_STORE 0x01 -#define I2O_EXEC_SW_DOWNLOAD_FLAG_EXPERIMENTAL 0x00 -#define I2O_EXEC_SW_DOWNLOAD_FLAG_OVERRIDE 0x02 - -#define I2O_EXEC_SW_TYPE_DDM 0x01 -#define I2O_EXEC_SW_TYPE_DDM_MPB 0x02 -#define I2O_EXEC_SW_TYPE_DDM_CONFIG_TABLE 0x03 -#define I2O_EXEC_SW_TYPE_IRTOS 0x11 -#define I2O_EXEC_SW_TYPE_IRTOS_PRIVATE_MODULE 0x12 -#define I2O_EXEC_SW_TYPE_IRTOS_DIALOG_TABLE 0x13 -#define I2O_EXEC_SW_TYPE_IOP_PRIVATE_MODULE 0x22 -#define I2O_EXEC_SW_TYPE_IOP_DIALOG_TABLE 0x23 - - -/* I2O ExecSwDownload/Upload/Remove SwID Structure */ - -typedef struct i2o_sw_id { - uint16_t ModuleID; - uint16_t OrganizationID; -} i2o_sw_id_t; - - -/* ExecSwDownload Function Message Frame structure. */ - -typedef struct i2o_exec_sw_donwload_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint8_t CurrentFragment; - uint8_t TotalFragments; - uint8_t SwType; - uint8_t DownloadFlags; - uint32_t SWSize; - i2o_sw_id_t SwID; - i2o_sg_element_t SGL; -} i2o_exec_sw_download_message_t; - - - - -/* ExecSwUpload Function Message Frame structure. */ - -typedef struct i2o_exec_sw_upload_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint8_t CurrentFragment; - uint8_t TotalFragments; - uint8_t SwType; - uint8_t UploadFlags; - uint32_t SWSize; - i2o_sw_id_t SwID; - i2o_sg_element_t SGL; -} i2o_exec_sw_upload_message_t; - - -/* ExecSwRemove Function Message Frame structure. */ - -typedef struct i2o_exec_sw_remove_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t reserved; - uint8_t SwType; - uint8_t RemoveFlags; - uint32_t SWSize; - i2o_sw_id_t SwID; -} i2o_exec_sw_remove_message_t; - - -/* ExecSysEnable Function Message Frame structure. */ - -typedef struct i2o_exec_sys_enable_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_exec_sys_enable_message_t; - - -/* ExecSysModify Function Message Frame structure. */ - -typedef struct i2o_exec_sys_modify_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_sg_element_t SGL; -} i2o_exec_sys_modify_message_t; - - -/* ExecSysQuiesce Function Message Frame structure. */ - -typedef struct i2o_exec_sys_quiesce_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_exec_sys_quiesce_message_t; - - -/* ExecSysTabSet (System Table) Function Message Frame structure. */ - -#define I2O_EXEC_SYS_TAB_IOP_ID_LOCAL_IOP 0x000 -#define I2O_EXEC_SYS_TAB_IOP_ID_LOCAL_HOST 0x001 -#define I2O_EXEC_SYS_TAB_IOP_ID_UNKNOWN_IOP 0xFFF -#define I2O_EXEC_SYS_TAB_HOST_UNIT_ID_LOCAL_UNIT 0x0000 -#define I2O_EXEC_SYS_TAB_HOST_UNIT_ID_UNKNOWN_UNIT 0xffff -#define I2O_EXEC_SYS_TAB_SEG_NUMBER_LOCAL_SEGMENT 0x000 -#define I2O_EXEC_SYS_TAB_SEG_NUMBER_UNKNOWN_SEGMENT 0xfff - - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_exec_sys_tab_set_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint16_t IOP_ID:12; - uint16_t reserved:4; - } s2; - uint16_t h1; - } u2; - uint16_t HostUnitID; - union { - struct { - uint32_t SegmentNumber:12; - uint32_t reserved1:20; - } s3; - uint32_t w3; - } u3; - i2o_sg_element_t SGL; -} i2o_exec_sys_tab_set_message_t; - -/* macros to access the bit fields in exec ddm enable message structure */ - -#define get_i2o_exec_sys_tab_set_IOP_ID(mp, hdl) \ - (mp)->u2.s2.IOP_ID -#define put_i2o_exec_sys_tab_set_IOP_ID(mp, id, hdl) \ - ((mp)->u2.s2.IOP_ID = (id)) - -#define get_i2o_exec_sys_tab_set_SegmentNumber(mp, hdl) \ - (mp)->u3.s3.SegmentNumber -#define put_i2o_exec_sys_tab_set_SegmentNumber(mp, id, hdl) \ - ((mp)->u3.s3.SegmentNumber = (id)) -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_exec_sys_tab_set_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - union { - struct { - uint16_t reserved:4; - uint16_t IOP_ID:12; - } s2; - uint16_t h1; - } u2; - uint16_t HostUnitID; - union { - struct { - uint32_t reserved1:20; - uint32_t SegmentNumnber:12; - } s3; - uint32_t w3; - } u3; - i2o_sg_element_t SGL; -} i2o_exec_sys_tab_set_message_t; - -/* macros to access the bit fields in exec ddm enable message structure */ - -#define get_i2o_exec_sys_tab_set_IOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u2.h1) & 0xFFF) - -#define put_i2o_exec_sys_tab_set_IOP_ID(mp, id, hdl) \ - ddi_put16(hdl, &(mp)->u2.h1, \ - (ddi_get16(hdl, &(mp)->u2.h1) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_i2o_exec_sys_tab_set_SegmentNumber(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u3.w3) & 0xFFF) -#define put_i2o_exec_sys_tab_set_SegmentNumber(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u3.w3, \ - (ddi_get32(hdl, &(mp)->u3.w3) & ~0xFFF) | ((id) & 0xFFF)) - -#endif - - -/* ExecSysTabSet (System Table) Header Reply structure. */ - -#define I2O_SET_SYSTAB_RESERVED_SZ 8 - -typedef struct i2o_set_systab_header { - uint8_t NumberEntries; - uint8_t SysTabVersion; - uint16_t reserved; - uint32_t CurrentChangeIndicator; - uint8_t reserved1[I2O_SET_SYSTAB_RESERVED_SZ]; -/* I2O_SYSTAB_ENTRY SysTabEntry[1]; */ -} i2o_set_systab_header_t; - - -#define I2O_RESOURCE_MANAGER_VERSION 0 - -typedef struct i2o_messenger_info { - uint32_t InboundMessagePortAddressLow; - uint32_t InboundMessagePortAddressHigh; -} i2o_messenger_info_t; - -/* ExecSysTabSet IOP Descriptor Entry structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_iop_entry { - uint16_t OrganizationID; - uint16_t reserved; - union { - struct { - uint32_t IOP_ID:12; - uint32_t reserved1:20; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t SegmentNumber:12; - uint16_t I2oVersion:4; - } s3; - uint16_t h1; - } u3; - uint8_t IopState; - uint8_t MessengerType; - uint16_t InboundMessageFrameSize; - uint16_t reserved2; - uint32_t LastChanged; - uint32_t IopCapabilities; - i2o_messenger_info_t MessengerInfo; -} i2o_iop_entry_t; - - -#define get_i2o_iop_entry_IOP_ID(mp, hdl) \ - ((mp)->u2.s2.IOP_ID) - -#define put_i2o_iop_entry_IOP_ID(mp, v, hdl) \ - ((mp)->u2.s2.IOP_ID) = (v) - -#define get_i2o_iop_entry_SegmentNumber(mp, hdl) \ - ((mp)->u3.s3.SegmentNumber) - -#define put_i2o_iop_entry_SegmentNumber(mp, v, hdl) \ - ((mp)->u3.s3.SegmentNumber) = (v) - -#define get_i2o_iop_entry_I2oVersion(mp, hdl) \ - ((mp)->u3.s3.I2oVersion) - -#define put_i2o_iop_entry_I2oVersion(mp, v, hdl) \ - ((mp)->u3.s3.I2oVersion) = (v) - -#endif - - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_iop_entry { - uint16_t OrganizationID; - uint16_t reserved; - union { - struct { - uint32_t reserved1:20; - uint32_t IOP_ID:12; - } s2; - uint32_t w2; - } u2; - union { - struct { - uint16_t I2oVersion:4; - uint16_t SegmentNumber:12; - } s3; - uint16_t h1; - } u3; - uint8_t IopState; - uint8_t MessengerType; - uint16_t InboundMessageFrameSize; - uint16_t reserved2; - uint32_t LastChanged; - uint32_t IopCapabilities; - i2o_messenger_info_t MessengerInfo; -} i2o_iop_entry_t; - - -#define get_i2o_iop_entry_IOP_ID(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u2.w2) & 0xFFF) - -#define put_i2o_iop_entry_IOP_ID(mp, v, hdl) \ - (ddi_put32(hdl, &(mp)->u2.w2) & 0xFFF, (v)) - -#define get_i2o_iop_entry_SegmentNumber(mp, hdl) \ - (ddi_get16(hdl, &(mp)->u3.h1) & 0xFFF) - -#define put_i2o_iop_entry_SegmentNumber(mp, v, hdl) \ - (ddi_put16(hdl, &(mp)->u3.h1) & 0xFFF, (v)) - -#define get_i2o_iop_entry_I2oVersion(mp, hdl) \ - ((ddi_get16(hdl, &(mp)->u3.h1) >> 12) & 0xF) - -#define put_i2o_iop_entry_I2oVersion(mp, v, hdl) \ - ((ddi_put16(hdl, &(mp)->u3.h1) >> 12) & 0xF, (v)) - -#endif - - -/* ************************************************************************** */ -/* Executive Parameter Groups */ -/* ************************************************************************** */ - - -#define I2O_EXEC_IOP_HARDWARE_GROUP_NO 0x0000 -#define I2O_EXEC_IOP_MESSAGE_IF_GROUP_NO 0x0001 -#define I2O_EXEC_EXECUTING_ENVIRONMENT_GROUP_NO 0x0002 -#define I2O_EXEC_EXECUTING_DDM_LIST_GROUP_NO 0x0003 -#define I2O_EXEC_DRIVER_STORE_GROUP_NO 0x0004 -#define I2O_EXEC_DRIVER_STORE_TABLE_GROUP_NO 0x0005 -#define I2O_EXEC_IOP_BUS_ATTRIBUTES_GROUP_NO 0x0006 -#define I2O_EXEC_IOP_SW_ATTRIBUTES_GROUP_NO 0x0007 -#define I2O_EXEC_HARDWARE_RESOURCE_TABLE_GROUP_NO 0x0100 -#define I2O_EXEC_LCT_SCALAR_GROUP_NO 0x0101 -#define I2O_EXEC_LCT_TABLE_GROUP_NO 0x0102 -#define I2O_EXEC_SYSTEM_TABLE_GROUP_NO 0x0103 -#define I2O_EXEC_EXTERNAL_CONN_TABLE_GROUP_NO 0x0104 - - -/* EXEC Group 0000h - IOP Hardware Parameter Group */ - -/* IOP HardWare Capabilities defines */ - -#define I2O_IOP_HW_CAP_SELF_BOOT 0x00000001 -#define I2O_IOP_HW_CAP_IRTOS_UPGRADEABLE 0x00000002 -#define I2O_IOP_HW_CAP_DOWNLOADABLE_DDM 0x00000004 -#define I2O_IOP_HW_CAP_INSTALLABLE_DDM 0x00000008 -#define I2O_IOP_HW_CAP_BATTERY_BACKUP_RAM 0x00000010 - -/* IOP Processor Type defines */ - -#define I2O_IOP_PROC_TYPE_INTEL_80960 0x00 -#define I2O_IOP_PROC_TYPE_AMD_29000 0x01 -#define I2O_IOP_PROC_TYPE_MOTOROLA_68000 0x02 -#define I2O_IOP_PROC_TYPE_ARM 0x03 -#define I2O_IOP_PROC_TYPE_MIPS 0x04 -#define I2O_IOP_PROC_TYPE_SPARC 0x05 -#define I2O_IOP_PROC_TYPE_POWER_PC 0x06 -#define I2O_IOP_PROC_TYPE_ALPHA 0x07 -#define I2O_IOP_PROC_TYPE_INTEL_X86 0x08 -#define I2O_IOP_PROC_TYPE_OTHER 0xFF - - -typedef struct i2o_exec_iop_hardware_scalar { - uint16_t I2oVendorID; - uint16_t ProductID; - uint32_t ProcessorMemory; - uint32_t PermMemory; - uint32_t HWCapabilities; - uint8_t ProcessorType; - uint8_t ProcessorVersion; -} i2o_exec_iop_hardware_scalar_t; - - -/* EXEC Group 0001h - IOP Message Interface Parameter Group */ - -/* InitCode defines */ -#define I2O_MESSAGE_IF_INIT_CODE_NO_OWNER 0x00 -#define I2O_MESSAGE_IF_INIT_CODE_BIOS 0x10 -#define I2O_MESSAGE_IF_INIT_CODE_OEM_BIOS_EXTENSION 0x20 -#define I2O_MESSAGE_IF_INIT_CODE_ROM_BIOS_EXTENSION 0x30 -#define I2O_MESSAGE_IF_INIT_CODE_OS 0x80 - -typedef struct i2o_exec_iop_message_if_scalar { - uint32_t InboundFrameSize; - uint32_t InboundSizeTarget; - uint32_t InboundMax; - uint32_t InboundTarget; - uint32_t InboundPoolCount; - uint32_t InboundCurrentFree; - uint32_t InboundCurrentPost; - uint16_t StaticCount; - uint16_t StaticInstanceCount; - uint16_t StaticLimit; - uint16_t StaticInstanceLimit; - uint32_t OutboundFrameSize; - uint32_t OutboundMax; - uint32_t OutboundMaxTarget; - uint32_t OutboundCurrentFree; - uint32_t OutboundCurrentPost; - uint8_t InitCode; -} i2o_exec_iop_message_if_scalar_t; - - -/* EXEC Group 0002h - Executing Environment Parameter Group */ - -typedef struct i2o_exec_execute_environment_scalar { - uint32_t MemTotal; - uint32_t MemFree; - uint32_t PageSize; - uint32_t EventQMax; - uint32_t EventQCurrent; - uint32_t DDMLoadMax; -} i2o_exec_execute_environment_scalar_t; - - -/* EXEC Group 0003h - Executing DDM's Parameter Group */ - -/* ModuleType Defines */ - -#define I2O_EXEC_DDM_MODULE_TYPE_OTHER 0x00 -#define I2O_EXEC_DDM_MODULE_TYPE_DOWNLOAD 0x01 -#define I2O_EXEC_DDM_MODULE_TYPE_EMBEDDED 0x22 - - -typedef struct i2o_exec_execute_ddm_table { - uint16_t DdmTID; - uint8_t ModuleType; - uint8_t reserved; - uint16_t I2oVendorID; - uint16_t ModuleID; - uint8_t ModuleName[I2O_MODULE_NAME_SZ]; - uint32_t ModuleVersion; - uint32_t DataSize; - uint32_t CodeSize; -} i2o_exec_execute_ddm_table_t; - - -/* EXEC Group 0004h - Driver Store Environment Parameter Group */ - - -typedef struct i2o_exec_driver_store_scalar { - uint32_t ModuleLimit; - uint32_t ModuleCount; - uint32_t CurrentSpace; - uint32_t FreeSpace; -} i2o_exec_driver_store_scalar_t; - - -/* EXEC Group 0005h - Driver Store Parameter Group */ - - -typedef struct i2o_exec_driver_store_table { - uint16_t StoredDdmIndex; - uint8_t ModuleType; - uint8_t reserved; - uint16_t I2oVendorID; - uint16_t ModuleID; - uint8_t ModuleName[I2O_MODULE_NAME_SZ]; - uint32_t ModuleVersion; - uint16_t DateDay; - uint16_t DateMonth; - uint32_t DateYear; - uint32_t ModuleSize; - uint32_t MpbSize; - uint32_t ModuleFlags; -} i2o_exec_driver_store_table_t; - - -/* EXEC Group 0006h - IOP's Bus Attributes Parameter Group */ - -#define I2O_EXEC_IOP_BUS_ATTRIB_SYSTEM_BUS 0x00 -#define I2O_EXEC_IOP_BUS_ATTRIB_BRIDGED_SYSTEM_BUS 0x01 -#define I2O_EXEC_IOP_BUS_ATTRIB_PRIVATE 0x02 - -typedef struct i2o_exec_iop_bus_attribute_table { - uint32_t BusID; - uint8_t BusType; - uint8_t MaxAdapters; - uint8_t AdapterCount; - uint8_t BusAttributes; -} i2o_exec_iop_bus_attribute_table_t; - - -/* EXEC Group 0007h - IOP's Bus Attributes Parameter Group */ - -#define I2O_EXEC_IOP_SW_CAP_IRTOS_I2O_COMPLIANT 0x00000001 -#define I2O_EXEC_IOP_SW_CAP_IRTOS_UPGRADEABLE 0x00000002 -#define I2O_EXEC_IOP_SW_CAP_DOWNLOADABLE_DDM 0x00000004 -#define I2O_EXEC_IOP_SW_CAP_INSTALLABLE_DDM 0x00000008 - -typedef struct i2o_exec_iop_sw_attributes_scalar { - uint16_t I2oVendorID; - uint16_t ProductID; - uint32_t CodeSize; - uint32_t SWCapabilities; -} i2o_exec_iop_sw_attributes_scalar_t; - - -/* EXEC Group 0100h - Hardware Resource Table Parameter Group */ - -typedef struct i2o_exec_hardware_resource_table { - uint32_t AdapterID; - uint16_t StateInfo; /* AdapterState plus Local TID */ - uint8_t BusNumber; - uint8_t BusType; - u_longlong_t PhysicalLocation; - uint32_t MemorySpace; - uint32_t IoSpace; -} i2o_exec_hardware_resource_table_t; - -/* EXEC Group 0101h - Logical Configuration Table Scalar Parameter Group */ - -typedef struct i2o_exec_lct_scalar { - uint16_t BootDevice; - uint32_t IopFlags; - uint32_t CurrentChangeIndicator; -} i2o_exec_lct_scalar_t; - -/* EXEC Group 0102h - Logical Configuration Table Parameter Group */ - -typedef struct i2o_exec_lct_table { - uint16_t LocalTID; - uint16_t UserTID; - uint16_t ParentTID; - uint16_t DdmTID; - uint32_t ChangeIndicator; - uint32_t DeviceFlags; - uint32_t ClassID; - uint32_t SubClass; - uint8_t IdentityTag[I2O_IDENTITY_TAG_SZ]; - uint32_t EventCapabilities; - uint8_t BiosInfo; -} i2o_exec_lct_table_t; - -/* EXEC Group 0103h - System Table Parameter Group */ - -#define I2O_MESSENGER_TYPE_MEMORY_MAPPED_MESSAGE_UNIT 0x0 - -typedef struct i2o_exec_system_table { - uint16_t IOP_ID; - uint16_t OrganizationID; - uint16_t SegmentNumber; - uint8_t Version; - uint8_t IopState; - uint8_t MessengerType; - uint8_t reserved; - uint32_t InboundMessagePortAddress; - uint16_t InboundMessageFrameSize; - uint32_t IopCapabilities; - i2o_messenger_info_t MessengerInfo; -} i2o_exec_system_table_t; - - -/* EXEC Group 0104h - External Connection Table Parameter Group */ - -#define I2O_EXEC_XCT_FLAGS_REMOTE_IOP_CREATED_CONNECTION 0x00 -#define I2O_EXEC_XCT_FLAGS_THIS_IOP_CREATED_CONNECTION 0x01 - -typedef struct i2o_exec_external_connection_table { - uint16_t LocalAliasTID; - uint16_t RemoteTID; - uint16_t RemoteIOP; - uint16_t RemoteUnitID; - uint8_t Flags; - uint8_t reserved; -} i2o_exec_external_connection_table_t; - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_I2OEXEC_H */ diff --git a/usr/src/uts/common/sys/i2o/i2omsg.h b/usr/src/uts/common/sys/i2o/i2omsg.h deleted file mode 100644 index bad40e2733..0000000000 --- a/usr/src/uts/common/sys/i2o/i2omsg.h +++ /dev/null @@ -1,1570 +0,0 @@ -/* - * Copyright (c) 1998-1999 by Sun Microsystems, Inc. - * All rights reserved. - */ - -/* - * ************************************************************************* - * All software on this website is made available under the following - * terms and conditions. By downloading this software, you agree to - * abide by these terms and conditions with respect to this software. - * - * I2O SIG All rights reserved. - * - * These header files are provided, pursuant to your I2O SIG membership - * agreement, free of charge on an as-is basis without warranty of any - * kind, either express or implied, including but not limited to, - * implied warranties or merchantability and fitness for a particular - * purpose. I2O SIG does not warrant that this program will meet the - * user's requirements or that the operation of these programs will be - * uninterrupted or error-free. Acceptance and use of this program - * constitutes the user's understanding that he will have no recourse - * to I2O SIG for any actual or consequential damages including, but - * not limited to, loss profits arising out of use or inability to use - * this program. - * - * Member is permitted to create deriavative works to this header-file - * program. However, all copies of the program and its derivative - * works must contain the I2O SIG copyright notice. - * ************************************************************************* - */ - -/* - * ************************************************************************* - * i2omsg.h -- I2O Message defintion file - * - * This file contains information presented in Chapter 3, 4 and 6 of - * the I2O(tm) Specification and most of the I2O Global defines and - * Typedefs. - * ************************************************************************* - */ - -#ifndef _SYS_I2OMSG_H -#define _SYS_I2OMSG_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#define I2OMSG_REV 1_5_4 /* I2OMsg header file revision string */ - -/* - * ************************************************************************* - * NOTES: - * - * Gets, reads, receives, etc. are all even numbered functions. - * Sets, writes, sends, etc. are all odd numbered functions. - * Functions that both send and receive data can be either but an attempt is - * made to use the function number that indicates the greater transfer amount. - * Functions that do not send or receive data use odd function numbers. - * - * Some functions are synonyms like read, receive and send, write. - * - * All common functions will have a code of less than 0x80. - * Unique functions to a class will start at 0x80. - * Executive Functions start at 0xA0. - * - * Utility Message function codes range from 0 - 0x1f - * Base Message function codes range from 0x20 - 0xfe - * Private Message function code is 0xff. - * ************************************************************************* - */ - -#include <sys/types.h> -#include <sys/dditypes.h> - -/* Set to 1 for 64 bit Context Fields */ -#define I2O_64BIT_CONTEXT 0 - -/* ************************************************************************** */ - -/* Common functions accross all classes. */ - -#define I2O_PRIVATE_MESSAGE 0xFF - -/* ************************************************************************** */ -/* Class ID and Code Assignments */ - - -#define I2O_CLASS_VERSION_10 0x00 -#define I2O_CLASS_VERSION_11 0x01 - -/* Class Code Names: Table 6-1 Class Code Assignments. */ - -#define I2O_CLASS_EXECUTIVE 0x000 -#define I2O_CLASS_DDM 0x001 -#define I2O_CLASS_RANDOM_BLOCK_STORAGE 0x010 -#define I2O_CLASS_SEQUENTIAL_STORAGE 0x011 -#define I2O_CLASS_LAN 0x020 -#define I2O_CLASS_WAN 0x030 -#define I2O_CLASS_FIBRE_CHANNEL_PORT 0x040 -#define I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL 0x041 -#define I2O_CLASS_SCSI_PERIPHERAL 0x051 -#define I2O_CLASS_ATE_PORT 0x060 -#define I2O_CLASS_ATE_PERIPHERAL 0x061 -#define I2O_CLASS_FLOPPY_CONTROLLER 0x070 -#define I2O_CLASS_FLOPPY_DEVICE 0x071 -#define I2O_CLASS_BUS_ADAPTER_PORT 0x080 -/* Class Codes 0x090 - 0x09f are reserved for Peer-to-Peer classes */ -#define I2O_CLASS_MATCH_ANYCLASS 0xffffffff - -#define I2O_SUBCLASS_i960 0x001 -#define I2O_SUBCLASS_HDM 0x020 -#define I2O_SUBCLASS_ISM 0x021 - -/* ************************************************************************** */ -/* Message Frame defines and structures */ - -/* Defines for the Version_Status field. */ - -#define I2O_VERSION_10 0x00 -#define I2O_VERSION_11 0x01 - -#define I2O_VERSION_OFFSET_NUMBER_MASK 0x07 -#define I2O_VERSION_OFFSET_SGL_TRL_OFFSET_MASK 0xF0 - -/* - * Defines for the Message Flags Field. - * Please Note that the FAIL bit is only set in the Transport Fail Message. - */ -#define I2O_MESSAGE_FLAGS_STATIC 0x01 -#define I2O_MESSAGE_FLAGS_64BIT_CONTEXT 0x02 -#define I2O_MESSAGE_FLAGS_MULTIPLE 0x10 -#define I2O_MESSAGE_FLAGS_FAIL 0x20 -#define I2O_MESSAGE_FLAGS_LAST 0x40 -#define I2O_MESSAGE_FLAGS_REPLY 0x80 - -/* Defines for Request Status Codes: Table 3-1 Reply Status Codes. */ - -#define I2O_REPLY_STATUS_SUCCESS 0x00 -#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01 -#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02 -#define I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER 0x03 -#define I2O_REPLY_STATUS_ERROR_DIRTY 0x04 -#define I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER 0x05 -#define I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER 0x06 -#define I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY 0x08 -#define I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x09 -#define I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x0A -#define I2O_REPLY_STATUS_TRANSACTION_ERROR 0x0B -#define I2O_REPLY_STATUS_PROGRESS_REPORT 0x80 - -/* - * DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes. - */ - -#define I2O_DETAIL_STATUS_SUCCESS 0x0000 -#define I2O_DETAIL_STATUS_BAD_KEY 0x0002 -#define I2O_DETAIL_STATUS_TCL_ERROR 0x0003 -#define I2O_DETAIL_STATUS_REPLY_BUFFER_FULL 0x0004 -#define I2O_DETAIL_STATUS_NO_SUCH_PAGE 0x0005 -#define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_SOFT 0x0006 -#define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_HARD 0x0007 -#define I2O_DETAIL_STATUS_CHAIN_BUFFER_TOO_LARGE 0x0009 -#define I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION 0x000A -#define I2O_DETAIL_STATUS_DEVICE_LOCKED 0x000B -#define I2O_DETAIL_STATUS_DEVICE_RESET 0x000C -#define I2O_DETAIL_STATUS_INAPPROPRIATE_FUNCTION 0x000D -#define I2O_DETAIL_STATUS_INVALID_INITIATOR_ADDRESS 0x000E -#define I2O_DETAIL_STATUS_INVALID_MESSAGE_FLAGS 0x000F -#define I2O_DETAIL_STATUS_INVALID_OFFSET 0x0010 -#define I2O_DETAIL_STATUS_INVALID_PARAMETER 0x0011 -#define I2O_DETAIL_STATUS_INVALID_REQUEST 0x0012 -#define I2O_DETAIL_STATUS_INVALID_TARGET_ADDRESS 0x0013 -#define I2O_DETAIL_STATUS_MESSAGE_TOO_LARGE 0x0014 -#define I2O_DETAIL_STATUS_MESSAGE_TOO_SMALL 0x0015 -#define I2O_DETAIL_STATUS_MISSING_PARAMETER 0x0016 -#define I2O_DETAIL_STATUS_TIMEOUT 0x0017 -#define I2O_DETAIL_STATUS_UNKNOWN_ERROR 0x0018 -#define I2O_DETAIL_STATUS_UNKNOWN_FUNCTION 0x0019 -#define I2O_DETAIL_STATUS_UNSUPPORTED_VERSION 0x001A -#define I2O_DEATIL_STATUS_DEVICE_BUSY 0x001B -#define I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE 0x001C - -/* Common I2O Field sizes */ - -#define I2O_TID_SZ 12 -#define I2O_FUNCTION_SZ 8 -#define I2O_UNIT_ID_SZ 16 -#define I2O_SEGMENT_NUMBER_SZ 12 - -#define I2O_IOP_ID_SZ 12 -#define I2O_GROUP_ID_SZ 16 -#define I2O_IOP_STATE_SZ 8 -#define I2O_MESSENGER_TYPE_SZ 8 - -#define I2O_CLASS_ID_SZ 12 -#define I2O_CLASS_ORGANIZATION_ID_SZ 16 - -#define I2O_4BIT_VERSION_SZ 4 -#define I2O_8BIT_FLAGS_SZ 8 -#define I2O_COMMON_LENGTH_FIELD_SZ 16 - -#define I2O_DEVID_DESCRIPTION_SZ 16 -#define I2O_DEVID_VENDOR_INFO_SZ 16 -#define I2O_DEVID_PRODUCT_INFO_SZ 16 -#define I2O_DEVID_REV_LEVEL_SZ 8 -#define I2O_MODULE_NAME_SZ 24 - -#define I2O_BIOS_INFO_SZ 8 - -#define I2O_RESERVED_4BITS 4 -#define I2O_RESERVED_8BITS 8 -#define I2O_RESERVED_12BITS 12 -#define I2O_RESERVED_16BITS 16 -#define I2O_RESERVED_20BITS 20 -#define I2O_RESERVED_24BITS 24 -#define I2O_RESERVED_28BITS 28 - -typedef uint32_t I2O_PARAMETER_TID; - -#if I2O_64BIT_CONTEXT - -typedef union { - void (* i2o_msg_complete)(void *, ddi_acc_handle_t); - uint64_t initiator_context_64bits; -} i2o_initiator_context_t; - -typedef uint64_t i2o_transaction_context_t; - -#else - -typedef union { - void (* i2o_msg_complete)(void *, ddi_acc_handle_t); - uint32_t initiator_context_32bits; -} i2o_initiator_context_t; - -typedef uint32_t i2o_transaction_context_t; - -#endif - -/* Serial Number format defines */ - -#define I2O_SERIAL_FORMAT_UNKNOWN 0 -#define I2O_SERIAL_FORMAT_BINARY 1 -#define I2O_SERIAL_FORMAT_ASCII 2 -#define I2O_SERIAL_FORMAT_UNICODE 3 -#define I2O_SERIAL_FORMAT_LAN_MAC 4 -#define I2O_SERIAL_FORMAT_WAN 5 - -/* Special TID Assignments */ - -#define I2O_IOP_TID 0 -#define I2O_HOST_TID 1 - - -/* ************************************************************************** */ - -/* I2O Message Frame common for all messages */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_message_frame { - uint8_t VersionOffset; - uint8_t MsgFlags; - uint16_t MessageSize; - union { - struct { - uint32_t TargetAddress:12; - uint32_t InitiatorAddress:12; - uint32_t Function:8; - } s2; - uint32_t w2; - } u2; - i2o_initiator_context_t InitiatorContext; -} i2o_message_frame_t; - -/* macros to access the bit fields in Message Frame */ - -#define get_msg_TargetAddress(mp, hdl) \ - (mp)->u2.s2.TargetAddress -#define put_msg_TargetAddress(mp, id, hdl) \ - ((mp)->u2.s2.TargetAddress = (id)) -#define get_msg_InitiatorAddress(mp, hdl) \ - (mp)->u2.s2.InitiatorAddress -#define put_msg_InitiatorAddress(mp, id, hdl) \ - ((mp)->u2.s2.InitiatorAddress = (id)) -#define get_msg_Function(mp, hdl) \ - (mp)->u2.s2.Function -#define put_msg_Function(mp, n, hdl) \ - ((mp)->u2.s2.Function = (n)) -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_message_frame { - uint8_t VersionOffset; - uint8_t MsgFlags; - uint16_t MessageSize; - union { - struct { - uint32_t Function:8; - uint32_t InitiatorAddress:12; - uint32_t TargetAddress:12; - } s2; - uint32_t w2; - } u2; - i2o_initiator_context_t InitiatorContext; -} i2o_message_frame_t; - -/* macros to access the bit fields in Message Frame */ - -#define get_msg_Function(mp, hdl) \ - (mp)->u2.s2.Function -#define put_msg_Function(mp, n, hdl) \ - ((mp)->u2.s2.Function = (n)) - -#define get_msg_TargetAddress(mp, hdl) \ - (ddi_get32(hdl, &(mp)->u2.w2) & 0xFFF) -#define put_msg_TargetAddress(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, \ - (ddi_get32(hdl, &(mp)->u2.w2) & ~0xFFF) | ((id) & 0xFFF)) - -#define get_msg_InitiatorAddress(mp, hdl) \ - ((ddi_get32(hdl, &(mp)->u2.w2) >> 12) & 0xFFF) -#define put_msg_InitiatorAddress(mp, id, hdl) \ - ddi_put32(hdl, &(mp)->u2.w2, (ddi_get32(hdl, &(mp)->u2.w2) & \ - ~0xFFF000) | (((id) & 0xFFF) << 12)) -#endif - - -/* ************************************************************************** */ - -/* Transaction Reply Lists (TRL) Control Word structure */ - -#define I2O_TRL_FLAGS_SINGLE_FIXED_LENGTH 0x00 -#define I2O_TRL_FLAGS_SINGLE_VARIABLE_LENGTH 0x40 -#define I2O_TRL_FLAGS_MULTIPLE_FIXED_LENGTH 0x80 - -typedef struct i2o_trl_control_word { - uint8_t TrlCount; - uint8_t TrlElementSize; - uint8_t reserved; - uint8_t TrlFlags; -#if I2O_64BIT_CONTEXT - uint32_t Padding; /* Padding for 64 bit */ -#endif -} i2o_trl_control_word_t; - -/* ************************************************************************** */ - -/* I2O Successful Single Transaction Reply Message Frame structure. */ - -typedef struct i2o_single_reply_message_frame { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t DetailedStatusCode; - uint8_t reserved; - uint8_t ReqStatus; - /* ReplyPayload */ -} i2o_single_reply_message_frame_t; - -/* ************************************************************************** */ - -/* I2O Successful Multiple Transaction Reply Message Frame structure. */ - -typedef struct i2o_multiple_reply_message_frame { - i2o_message_frame_t StdMessageFrame; - i2o_trl_control_word_t TrlControlWord; - uint16_t DetailedStatusCode; - uint8_t reserved; - uint8_t ReqStatus; - /* TransactionDetails[] */ -} i2o_multiple_reply_message_frame_t; - -/* ************************************************************************** */ - -/* I2O Private Message Frame structure. */ - -typedef struct i2o_private_message_frame { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t XFunctionCode; - uint16_t OrganizationID; - /* PrivatePayload[] */ -} i2o_private_message_frame_t; - -/* ************************************************************************** */ - -/* Message Failure Severity Codes */ - -#define I2O_SEVERITY_FORMAT_ERROR 0x1 -#define I2O_SEVERITY_PATH_ERROR 0x2 -#define I2O_SEVERITY_PATH_STATE 0x4 -#define I2O_SEVERITY_CONGESTION 0x8 - -/* Transport Failure Codes: Table 3-3 Mesasge Failure Codes */ - -#define I2O_FAILURE_CODE_TRANSPORT_SERVICE_SUSPENDED 0x81 -#define I2O_FAILURE_CODE_TRANSPORT_SERVICE_TERMINATED 0x82 -#define I2O_FAILURE_CODE_TRANSPORT_CONGESTION 0x83 -#define I2O_FAILURE_CODE_TRANSPORT_FAIL 0x84 -#define I2O_FAILURE_CODE_TRANSPORT_STATE_ERROR 0x85 -#define I2O_FAILURE_CODE_TRANSPORT_TIME_OUT 0x86 -#define I2O_FAILURE_CODE_TRANSPORT_ROUTING_FAILURE 0x87 -#define I2O_FAILURE_CODE_TRANSPORT_INVALID_VERSION 0x88 -#define I2O_FAILURE_CODE_TRANSPORT_INVALID_OFFSET 0x89 -#define I2O_FAILURE_CODE_TRANSPORT_INVALID_MSG_FLAGS 0x8A -#define I2O_FAILURE_CODE_TRANSPORT_FRAME_TOO_SMALL 0x8B -#define I2O_FAILURE_CODE_TRANSPORT_FRAME_TOO_LARGE 0x8C -#define I2O_FAILURE_CODE_TRANSPORT_INVALID_TARGET_ID 0x8D -#define I2O_FAILURE_CODE_TRANSPORT_INVALID_INITIATOR_ID 0x8E -#define I2O_FAILURE_CODE_TRANSPORT_INVALID_INITIATOR_CONTEXT 0x8F -#define I2O_FAILURE_CODE_TRANSPORT_UNKNOWN_FAILURE 0xFF - -/* IOP_ID and Severity sizes */ - -#define I2O_FAILCODE_SEVERITY_SZ 8 -#define I2O_FAILCODE_CODE_SZ 8 - -/* I2O Transport Message Reply for Message Failure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_failure_reply_message_frame { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint8_t LowestVersion; - uint8_t HighestVersion; - uint8_t Severity; - uint8_t FailureCode; - union { - struct { - uint16_t FailingIOP_ID:12; - uint16_t reserved:4; - } s; - uint16_t h; - } u1; - uint16_t FailingHostUnitID; - uint32_t AgeLimit; - i2o_message_frame_t *PreservedMFA; -} i2o_failure_reply_message_frame_t; - -/* macros to access the bit field(s) */ - -#define get_reply_msg_FailingIOP_ID(p, hdl) \ - ((p)->u1.s.FailingIOP_ID) -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_failure_reply_message_frame { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint8_t LowestVersion; - uint8_t HighestVersion; - uint8_t Severity; - uint8_t FailureCode; - union { - struct { - uint16_t reserved:4; - uint16_t FailingIOP_ID:12; - } s; - uint16_t h; - } u1; - uint16_t FailingHostUnitID; - uint32_t AgeLimit; - i2o_message_frame_t *PreservedMFA; -} i2o_failure_reply_message_frame_t; - -/* macros to access the bit field(s) */ - -#define get_reply_msg_FailingIOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u1.h) & 0xFFF) -#endif - -/* I2O Transport Message Reply for Transaction Error. */ - -typedef struct i2o_transaction_error_reply_message_frame { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t DetailedStatusCode; - uint8_t reserved; - uint8_t ReqStatus; /* Should Transaction Error */ - uint32_t ErrorOffset; - uint8_t BitOffset; - uint8_t reserved1; - uint16_t reserved2; -} i2o_transaction_error_reply_message_frame_t; - -/* ************************************************************************** */ - -/* Misc. commonly used structures */ - -#define I2O_MAX_SERIAL_NUMBER_SZ 256 - -typedef struct i2o_serial_info { - uint8_t SerialNumberLength; - uint8_t SerialNumberFormat; - uint8_t SerialNumber[I2O_MAX_SERIAL_NUMBER_SZ]; -} i2o_serial_info_t; - - -/* ************************************************************************** */ -/* Hardware Resource Table (HRT) and Logical Configuration Table (LCT) */ -/* ************************************************************************** */ - -/* Bus Type Code defines */ - -#define I2O_LOCAL_BUS 0 -#define I2O_ISA_BUS 1 -#define I2O_EISA_BUS 2 -#define I2O_PCI_BUS 4 -#define I2O_PCMCIA_BUS 5 -#define I2O_NUBUS_BUS 6 -#define I2O_CARDBUS_BUS 7 -#define I2O_OTHER_BUS 0x80 - -#define I2O_HRT_STATE_SZ 4 -#define I2O_HRT_BUS_NUMBER_SZ 8 -#define I2O_HRT_BUS_TYPE_SZ 8 - - -/* Bus Structures */ - -/* PCI Bus */ -typedef struct i2o_pci_bus_info { - uint8_t PciFunctionNumber; - uint8_t PciDeviceNumber; - uint8_t PciBusNumber; - uint8_t reserved; - uint16_t PciVendorID; - uint16_t PciDeviceID; -} i2o_pci_bus_info_t; - -/* Local Bus */ -typedef struct i2o_local_bus_info { - uint16_t LbBaseIOPort; - uint16_t reserved; - uint32_t LbBaseMemoryAddress; -} i2o_local_bus_info_t; - -/* ISA Bus */ -typedef struct i2o_isa_bus_info { - uint16_t IsaBaseIOPort; - uint8_t CSN; - uint8_t reserved; - uint32_t IsaBaseMemoryAddress; -} i2o_isa_bus_info_t; - -/* EISA Bus */ -typedef struct i2o_eisa_bus_info { - uint16_t EisaBaseIOPort; - uint8_t reserved; - uint8_t EisaSlotNumber; - uint32_t EisaBaseMemoryAddress; -} i2o_eisa_bus_info_t; - -/* Other Bus */ -typedef struct i2o_other_bus_info { - uint16_t BaseIOPort; - uint16_t reserved; - uint32_t BaseMemoryAddress; -} i2o_other_bus_info_t; - - -/* HRT Entry Block */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_hrt_entry { - uint32_t AdapterID; - union { - struct { - uint16_t ControllingTID:12; - uint16_t AdapterState:4; - } s2; - uint16_t h2; - } u2; - uint8_t BusNumber; - uint8_t BusType; - union { - /* PCI Bus */ - i2o_pci_bus_info_t PCIBus; - - /* Local Bus */ - i2o_local_bus_info_t LocalBus; - - /* ISA Bus */ - i2o_isa_bus_info_t ISABus; - - /* EISA Bus */ - i2o_eisa_bus_info_t EISABus; - - /* Other. */ - i2o_other_bus_info_t OtherBus; - } uBus; -} i2o_hrt_entry_t; - -/* macros to access the bit fields */ - -#define get_hrt_entry_ControllingTID(p, hdl) (p)->u2.s2.ControllingTID -#define get_hrt_entry_AdapterState(p, hdl) (p)->u2.s2.AdapterState - -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_hrt_entry { - uint32_t AdapterID; - union { - struct { - uint16_t AdapterState:4; - uint16_t ControllingTID:12; - } s2; - uint16_t h2; - } u2; - uint8_t BusNumber; - uint8_t BusType; - union { - /* PCI Bus */ - i2o_pci_bus_info_t PCIBus; - - /* Local Bus */ - i2o_local_bus_info_t LocalBus; - - /* ISA Bus */ - i2o_isa_bus_info_t ISABus; - - /* EISA Bus */ - i2o_eisa_bus_info_t EISABus; - - /* Other. */ - i2o_other_bus_info_t OtherBus; - } uBus; -} i2o_hrt_entry_t; - -/* macros to access the bit fields */ - -#define get_hrt_entry_ControllingTID(p, hdl) \ - (ddi_get16(hdl, &(p)->u2.h2) & 0xFFF) -#define get_hrt_entry_AdapterState(p, hdl) \ - ((ddi_get16(hdl, &(p)->u2.h2) >> 12) & 0xF) -#endif - -/* I2O Hardware Resource Table structure. */ - -typedef struct i2o_hrt { - uint16_t NumberEntries; - uint8_t EntryLength; - uint8_t HRTVersion; - uint32_t CurrentChangeIndicator; - i2o_hrt_entry_t HRTEntry[1]; -} i2o_hrt_t; - - -/* ************************************************************************** */ -/* Logical Configuration Table */ -/* ************************************************************************** */ - -/* I2O Logical Configuration Table structures. */ - -#define I2O_IDENTITY_TAG_SZ 8 - -/* I2O Logical Configuration Table Device Flags */ - -#define I2O_LCT_DEVICE_FLAGS_CONF_DIALOG_REQUEST 0x01 -#define I2O_LCT_DEVICE_FLAGS_MORE_THAN_1_USER 0x02 -#define I2O_LCT_DEVICE_FLAGS_PEER_SERVICE_DISABLED 0x10 -#define I2O_LCT_DEVICE_FLAGS_MANAGEMENT_SERVICE_DISABLED 0x20 - -/* LCT Entry Block */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_lct_entry { - union { - struct { - uint32_t TableEntrySize:16; - uint32_t LocalTID:12; - uint32_t reserved:4; - } s1; - uint32_t w1; - } u1; - uint32_t ChangeIndicator; - uint32_t DeviceFlags; - union { - struct i2o_class_id { - uint32_t Class:12; - uint32_t Version:4; - uint32_t OrganizationID:16; - } s4; - uint32_t w4; - } u4; - uint32_t SubClassInfo; - union { - struct { - uint32_t UserTID:12; - uint32_t ParentTID:12; - uint32_t BiosInfo:8; - } s6; - uint32_t w6; - } u6; - uint8_t IdentityTag[I2O_IDENTITY_TAG_SZ]; - uint32_t EventCapabilities; -} i2o_lct_entry_t; - -/* macros to access the bit fields */ - -#define get_lct_entry_LocalTID(p, hdl) (p)->u1.s1.LocalTID -#define get_lct_entry_TableEntrySize(p, hdl) (p)->u1.s1.TableEntrySize - -#define get_lct_entry_Class(p, hdl) (p)->u4.s4.Class -#define get_lct_entry_Version(p, hdl) (p)->u4.s4.Version -#define get_lct_entry_OrganizationID(p, hdl) (p)->u4.s4.OrganizationID - -#define get_lct_entry_BiosInfo(p, hdl) (p)->u6.s6.BiosInfo -#define get_lct_entry_ParentTID(p, hdl) (p)->u6.s6.ParentTID -#define get_lct_entry_UserTID(p, hdl) (p)->u6.s6.UserTID - -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_lct_entry { - union { - struct { - uint32_t reserved:4; - uint32_t LocalTID:12; - uint32_t TableEntrySize:16; - } s1; - uint32_t w1; - } u1; - uint32_t ChangeIndicator; - uint32_t DeviceFlags; - union { - struct i2o_class_id { - uint32_t OrganizationID:16; - uint32_t Version:4; - uint32_t Class:12; - } s4; - uint32_t w4; - } u4; - uint32_t SubClassInfo; - union { - struct { - uint32_t BiosInfo:8; - uint32_t ParentTID:12; - uint32_t UserTID:12; - } s6; - uint32_t w6; - } u6; - uint8_t IdentityTag[I2O_IDENTITY_TAG_SZ]; - uint32_t EventCapabilities; -} i2o_lct_entry_t; - -/* macros to access the bit fields */ - -#define get_lct_entry_TableEntrySize(p, hdl) \ - (ddi_get32(hdl, &(p)->u1.w1) & 0xFFFF) -#define get_lct_entry_LocalTID(p, hdl) \ - ((ddi_get32(hdl, (p)->u1.w1) >> 16) & 0xFFF) - -#define get_lct_entry_OrganizationID(p, hdl) \ - ((ddi_get16(hdl, (p)->u4.w4) >> 16) & 0xFFFF) -#define get_lct_entry_Version(p, hdl) \ - ((ddi_get32(hdl, &(p)->u4.w4) >> 12) & 0xF) -#define get_lct_entry_Class(p, hdl) \ - (ddi_get32(hdl, &(p)->u4.w4) & 0xFFF) - -#define get_lct_entry_BiosInfo(p, hdl) (p)->u6.s6.BiosInfo -#define get_lct_entry_ParentTID(p, hdl) \ - ((ddi_get32(hdtl, &(p)->u6.w6) >> 12) & 0xFFF) -#define get_lct_entry_UserTID(p, hdl) \ - (ddi_get32(hdtl, &(p)->u6.w6) & 0xFFF) - -#endif - -/* I2O Logical Configuration Table structure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_lct { - uint16_t TableSize; - union { - struct { - uint16_t BootDeviceTID:12; - uint16_t LctVer:4; - } s1; - uint16_t h1; - } u1; - uint32_t IopFlags; - uint32_t CurrentChangeIndicator; - i2o_lct_entry_t LCTEntry[1]; -} i2o_lct_t; - -/* macros to access the bit fields */ - -#define get_lct_BootDeviceTID(p, hdl) (p)->u1.s1.BootDeviceTID -#define get_lct_LctVer(p, hdl) (p)->u1.s1.LctVer - -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_lct { - uint16_t TableSize; - union { - struct { - uint16_t LctVer:4; - uint16_t BootDeviceTID:12; - } s1; - uint16_t h1; - } u1; - uint32_t IopFlags; - uint32_t CurrentChangeIndicator; - i2o_lct_entry_t LCTEntry[1]; -} i2o_lct_t; - -/* macros to access the bit fields */ - -#define get_lct_BootDeviceTID(p, hdl) \ - ((ddi_get32(hdl, &(p)->u1.w1) >> 16) & 0xFFF) -#define get_lct_LctVer(p, hdl) \ - ((ddi_get32(hdl, &(p)->u1.w1) >> 28) & 0xF) - -#endif - -/* ************************************************************************** */ - -/* Memory Addressing structures and defines. */ - -/* SglFlags defines. */ - -#define I2O_SGL_FLAGS_LAST_ELEMENT 0x80 -#define I2O_SGL_FLAGS_END_OF_BUFFER 0x40 - -#define I2O_SGL_FLAGS_IGNORE_ELEMENT 0x00 -#define I2O_SGL_FLAGS_TRANSPORT_ELEMENT 0x04 -#define I2O_SGL_FLAGS_BIT_BUCKET_ELEMENT 0x08 -#define I2O_SGL_FLAGS_IMMEDIATE_DATA_ELEMENT 0x0C -#define I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT 0x10 -#define I2O_SGL_FLAGS_PAGE_LIST_ADDRESS_ELEMENT 0x20 -#define I2O_SGL_FLAGS_CHAIN_POINTER_ELEMENT 0x30 -#define I2O_SGL_FLAGS_LONG_TRANSACTION_ELEMENT 0x40 -#define I2O_SGL_FLAGS_SHORT_TRANSACTION_ELEMENT 0x70 -#define I2O_SGL_FLAGS_SGL_ATTRIBUTES_ELEMENT 0x7C - -#define I2O_SGL_FLAGS_BC0 0x01 -#define I2O_SGL_FLAGS_BC1 0x02 -#define I2O_SGL_FLAGS_DIR 0x04 -#define I2O_SGL_FLAGS_LOCAL_ADDRESS 0x08 - -#define I2O_SGL_FLAGS_CONTEXT_COUNT_MASK 0x03 -#define I2O_SGL_FLAGS_ADDRESS_MODE_MASK 0x3C -#define I2O_SGL_FLAGS_NO_CONTEXT 0x00 - -/* Scatter/Gather Truth Table */ - -/* - * - * typedef enum _SG_TYPE { - * INVALID, - * Ignore, - * TransportDetails, - * BitBucket, - * ImmediateData, - * Simple, - * PageList, - * ChainPointer, - * ShortTransaction, - * LongTransaction, - * SGLAttributes, - * INVALID/ReservedLongFormat, - * INVALID/ReservedShortFormat - * } SG_TYPE, *PSG_TYPE; - * - * - * 0x00 Ignore; - * 0x04 TransportDetails; - * 0x08 BitBucket; - * 0x0C ImmediateData; - * 0x10 Simple; - * 0x14 Simple; - * 0x18 Simple; - * 0x1C Simple; - * 0x20 PageList; - * 0x24 PageList; - * 0x28 PageList; - * 0x2C PageList; - * 0x30 ChainPointer; - * 0x34 INVALID; - * 0x38 ChainPointer; - * 0x3C INVALID; - * 0x40 LongTransaction; - * 0x44 INVALID/ReservedLongFormat; - * 0x48 BitBucket; - * 0x4C ImmediateData; - * 0x50 Simple; - * 0x54 Simple; - * 0x58 Simple; - * 0x5C Simple; - * 0x60 PageList; - * 0x64 PageList; - * 0x68 PageList; - * 0x6C PageList; - * 0x70 ShortTransaction; - * 0x74 INVALID/ReservedShortFormat; - * 0x78 INVALID/ReservedShortFormat; - * 0X7C SGLATTRIBUTES; - */ - - -/* 32 Bit Context Field defines */ - -#define I2O_SGL_FLAGS_CONTEXT32_NULL 0x00 -#define I2O_SGL_FLAGS_CONTEXT32_U32 0x01 -#define I2O_SGL_FLAGS_CONTEXT32_U64 0x02 -#define I2O_SGL_FLAGS_CONTEXT32_U96 0x03 - -#define I2O_SGL_FLAGS_CONTEXT32_NULL_SZ 0x00 -#define I2O_SGL_FLAGS_CONTEXT32_U32_SZ 0x04 -#define I2O_SGL_FLAGS_CONTEXT32_U64_SZ 0x08 -#define I2O_SGL_FLAGS_CONTEXT32_U96_SZ 0x0C - -/* 64 Bit Context Field defines */ - -#define I2O_SGL_FLAGS_CONTEXT64_NULL 0x00 -#define I2O_SGL_FLAGS_CONTEXT64_U64 0x01 -#define I2O_SGL_FLAGS_CONTEXT64_U128 0x02 -#define I2O_SGL_FLAGS_CONTEXT64_U192 0x03 - -#define I2O_SGL_FLAGS_CONTEXT64_NULL_SZ 0x00 -#define I2O_SGL_FLAGS_CONTEXT64_U64_SZ 0x08 -#define I2O_SGL_FLAGS_CONTEXT64_U128_SZ 0x10 -#define I2O_SGL_FLAGS_CONTEXT64_U192_SZ 0x18 - -/* SGL Attribute Element defines */ - -#define I2O_SGL_ATTRIBUTE_FLAGS_BIT_BUCKET_HINT 0x0400 -#define I2O_SGL_ATTRIBUTE_FLAGS_IMMEDIATE_DATA_HINT 0x0200 -#define I2O_SGL_ATTRIBUTE_FLAGS_LOCAL_ADDRESS_HINT 0x0100 -#define I2O_SGL_ATTRIBUTE_FLAGS_32BIT_TRANSACTION 0x0000 -#define I2O_SGL_ATTRIBUTE_FLAGS_64BIT_TRANSACTION 0x0004 -#define I2O_SGL_ATTRIBUTE_FLAGS_32BIT_LOCAL_ADDRESS 0x0000 - -/* SG Size defines */ - -#define I2O_SG_COUNT_SZ 24 -#define I2O_SG_FLAGS_SZ 8 - -/* Standard Flags and Count fields for SG Elements */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef union i2o_flags_count { - struct { - uint32_t Count:24; - uint32_t Flags:8; - } flags_count; - uint32_t cword; -} i2o_flags_count_t; - -#define get_flags_count_Count(p, hdl) (p)->flags_count.Count -#define put_flags_count_Count(p, v, hdl) ((p)->flags_count.Count = (v)) -#define get_flags_count_Flags(p, hdl) (p)->flags_count.Flags -#define put_flags_count_Flags(p, v, hdl) ((p)->flags_count.Flags = (v)) - -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef union i2o_flags_count { - struct { - uint32_t Flags:8; - uint32_t Count:24; - } flags_count; - uint32_t cword; -} i2o_flags_count_t; - -#define get_flags_count_Count(p, hdl) \ - (ddi_get32(hdl, &(p)->cword) & 0xFFFFFF) -#define put_flags_count_Count(p, v, hdl) \ - ddi_put32(hdl, &(p)->cword, \ - (ddi_get32(hdl, &(p)->cword) & ~0xFFFFFF) | \ - ((uint32_t)(v) & 0xFFFFFF)) -#define get_flags_count_Flags(p, hdl) \ - ((ddi_get32(hdl, &(p)->cword) >> 24) & 0xFF) -#define put_flags_count_Flags(p, v, hdl) \ - ddi_put32(hdl, &(p)->cword, \ - (ddi_get32(hdl, &(p)->cword) & ~0xFF000000) | ((uint32_t)(v) << 24)) -#endif - -/* Bit Bucket Element */ - -typedef struct i2o_sge_bit_bucket_element { - i2o_flags_count_t FlagsCount; - uint32_t BufferContext; -} i2o_sge_bit_bucket_element_t; - -/* Chain Addressing Scatter-Gather Element */ - -typedef struct i2o_sge_chain_element { - i2o_flags_count_t FlagsCount; - uint32_t PhysicalAddress; -} i2o_sge_chain_element_t; - -/* Chain Addressing with Context Scatter-Gather Element */ - -typedef struct i2o_sge_chain_context_element { - i2o_flags_count_t FlagsCount; - uint32_t Context[1]; - uint32_t PhysicalAddress; -} i2o_sge_chain_context_element_t; - -/* Ignore Scatter-Gather Element */ - -typedef struct i2o_sge_ignore_element { - i2o_flags_count_t FlagsCount; -} i2o_sge_ignore_element_t; - -/* Immediate Data Element */ - -typedef struct i2o_sge_immediate_data_element { - i2o_flags_count_t FlagsCount; -} i2o_sge_immediate_data_element_t; - -/* Immediate Data with Context Element */ - -typedef struct i2o_sge_immediate_data_context_element { - i2o_flags_count_t FlagsCount; - uint32_t BufferContext; -} i2o_sge_immediate_data_context_element_t; - -/* Long Transaction Parameters Element */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_sge_long_transaction_element { - union { - struct { - uint32_t LongElementLength:24; - uint32_t Flags:8; - } s1; - uint32_t w1; - } u1; - uint32_t BufferContext; -} i2o_sge_long_transaction_element_t; - -#define get_sge_long_LongElementLength(p, hdl) \ - (p)->u1.s1.LongElementLength -#define put_sge_long_LongElementLength(p, v, hdl) \ - ((p)->u1.s1.LongElementLength = (v)) -#define get_sge_long_Flags(p, hdl) \ - (p)->u1.s1.Flags -#define put_sge_long_Flags(p, v, hdl) \ - ((p)->u1.s1.Flags = (v)) - -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_sge_long_transaction_element { - union { - struct { - uint32_t Flags:8; - uint32_t LongElementLength:24; - } s1; - uint32_t w1; - } u1; - uint32_t BufferContext; -} i2o_sge_long_transaction_element_t; - -#define get_sge_long_LongElementLength(p, hdl) \ - (ddi_get32(hdl, &(p)->u1.w1) & 0xFFFFFF) -#define put_sge_long_LongElementLength(p, v, hdl) \ - ddi_put32(hdl, &(p)->u1.w1, \ - (ddi_get32(hdl, &(p)->u1.w1) & ~0xFFFFFF) | \ - ((uint32_t)(v) & 0xFFFFFF)) -#define get_sge_long_Flags(p, hdl) \ - (ddi_get32(hdl, &(p)->u1.w1) >> 24) -#define put_sge_long_Flags(p, v, hdl) \ - ddi_put32(hdl, &(p)->u1.w1, \ - (ddi_get32(hdl, &(p)->u1.w1) & ~0xFF000000) | \ - ((uint32_t)(v) << 24)) -#endif - -/* Page List Scatter-Gather Element */ - -typedef struct i2o_sge_page_element { - i2o_flags_count_t FlagsCount; - uint32_t PhysicalAddress[1]; -} i2o_sge_page_element_t; - -/* Page List with Context Scatter-Gather Element */ - -typedef struct i2o_sge_page_context_element { - i2o_flags_count_t FlagsCount; - uint32_t BufferContext[1]; - uint32_t PhysicalAddress[1]; -} i2o_sge_page_context_element_t; - -/* SGL Attribute Element */ - -typedef struct i2o_sge_sgl_attributes_element { - uint16_t SglAttributeFlags; - uint8_t ElementLength; - uint8_t Flags; - uint32_t PageFrameSize; -} i2o_sge_sgl_attributes_element_t; - -/* Short Transaction Parameters Element */ - -typedef struct i2o_sge_short_transaction_element { - uint16_t ClassFields; - uint8_t ElementLength; - uint8_t Flags; - uint32_t BufferContext; -} i2o_sge_short_transaction_element_t; - -/* Simple Addressing Scatter-Gather Element */ - -typedef struct i2o_sge_simple_element { - i2o_flags_count_t FlagsCount; - uint32_t PhysicalAddress; -} i2o_sge_simple_element_t; - -/* Simple Addressing with Context Scatter-Gather Element */ - -typedef struct i2o_sge_simple_context_element { - i2o_flags_count_t FlagsCount; - uint32_t BufferContext[1]; - uint32_t PhysicalAddress; -} i2o_sge_simple_context_element_t; - -/* Transport Detail Element */ - -typedef struct i2o_sge_transport_element { - uint_t LongElementLength:24; - uint_t Flags:8; -} i2o_sge_transport_element_t; - -typedef struct i2o_sg_element { - union { - /* Bit Bucket Element */ - i2o_sge_bit_bucket_element_t BitBucket; - - /* Chain Addressing Element */ - i2o_sge_chain_element_t Chain; - - /* Chain Addressing with Context Element */ - i2o_sge_chain_context_element_t ChainContext; - - /* Ignore Scatter-Gather Element */ - i2o_sge_ignore_element_t Ignore; - - /* Immediate Data Element */ - i2o_sge_immediate_data_element_t ImmediateData; - - /* Immediate Data with Context Element */ - i2o_sge_immediate_data_context_element_t ImmediateDataContext; - - /* Long Transaction Parameters Element */ - i2o_sge_long_transaction_element_t LongTransaction; - - /* Page List Element */ - i2o_sge_page_element_t Page; - - /* Page List with Context Element */ - i2o_sge_page_context_element_t PageContext; - - /* SGL Attribute Element */ - i2o_sge_sgl_attributes_element_t SGLAttribute; - - /* Short Transaction Parameters Element */ - i2o_sge_short_transaction_element_t ShortTransaction; - - /* Simple Addressing Element */ - i2o_sge_simple_element_t Simple[1]; - - /* Simple Addressing with Context Element */ - i2o_sge_simple_context_element_t SimpleContext[1]; - - /* Transport Detail Element */ - i2o_sge_transport_element_t Transport; - } u1; -} i2o_sg_element_t; - -/* ************************************************************************** */ -/* Basic Parameter Group Access */ -/* ************************************************************************** */ - -/* Operation Function Numbers */ - -#define I2O_PARAMS_OPERATION_FIELD_GET 0x0001 -#define I2O_PARAMS_OPERATION_LIST_GET 0x0002 -#define I2O_PARAMS_OPERATION_MORE_GET 0x0003 -#define I2O_PARAMS_OPERATION_SIZE_GET 0x0004 -#define I2O_PARAMS_OPERATION_TABLE_GET 0x0005 -#define I2O_PARAMS_OPERATION_FIELD_SET 0x0006 -#define I2O_PARAMS_OPERATION_LIST_SET 0x0007 -#define I2O_PARAMS_OPERATION_ROW_ADD 0x0008 -#define I2O_PARAMS_OPERATION_ROW_DELETE 0x0009 -#define I2O_PARAMS_OPERATION_TABLE_CLEAR 0x000A - -/* Operations List Header */ - -typedef struct i2o_param_operations_list_header { - uint16_t OperationCount; - uint16_t Reserved; -} i2o_param_operations_list_header_t; - -/* Results List Header */ - -typedef struct i2o_param_results_list_header { - uint16_t ResultCount; - uint16_t Reserved; -} i2o_param_results_list_header_t; - -/* Read Operation Result Block Template Structure */ - -typedef struct i2o_param_read_operation_result { - uint16_t BlockSize; - uint8_t BlockStatus; - uint8_t ErrorInfoSize; - /* Operations Results */ - /* Pad (if any) */ - /* ErrorInformation (if any) */ -} i2o_param_read_operation_result_t; - -typedef struct i2o_table_read_operation_result { - uint16_t BlockSize; - uint8_t BlockStatus; - uint8_t ErrorInfoSize; - uint16_t RowCount; - uint16_t MoreFlag; - /* Operations Results */ - /* Pad (if any) */ - /* ErrorInformation (if any) */ -} i2o_table_read_operation_result_t; - -/* Error Information Template Structure */ - -typedef struct i2o_param_error_info_template { - uint16_t OperationCode; - uint16_t GroupNumber; - uint16_t FieldIdx; - uint8_t AdditionalStatus; - uint8_t NumberKeys; - /* List of Key Values (variable) */ - /* Pad (if any) */ -} i2o_param_error_info_template_t; - -/* Operation Template for Specific Fields */ - -typedef struct i2o_param_operation_specific_template { - uint16_t Operation; - uint16_t GroupNumber; - uint16_t FieldCount; - uint16_t FieldIdx[1]; - /* Pad (if any) */ -} i2o_param_operation_specific_template_t; - -/* Operation Template for All Fields */ - -typedef struct i2o_param_operation_all_template { - uint16_t Operation; - uint16_t GroupNumber; - uint16_t FieldCount; - /* Pad (if any) */ -} i2o_param_operation_all_template_t; - -/* Operation Template for All List Fields */ - -typedef struct i2o_param_operation_all_list_template { - uint16_t Operation; - uint16_t GroupNumber; - uint16_t FieldCount; - uint16_t KeyCount; - uint8_t KeyValue; - /* Pad (if any) */ -} i2o_param_operation_all_list_template_t; - -/* Modify Operation Result Block Template Structure */ - -typedef struct i2o_param_modify_operation_result { - uint16_t BlockSize; - uint8_t BlockStatus; - uint8_t ErrorInfoSize; - /* ErrorInformation (if any) */ -} i2o_param_modify_operation_result_t; - -/* Operation Template for Row Delete */ - -typedef struct i2o_param_operation_row_delete_template { - uint16_t Operation; - uint16_t GroupNumber; - uint16_t RowCount; - uint8_t KeyValue; -} i2o_param_operation_row_delete_template_t; - -/* Operation Template for Table Clear */ - -typedef struct i2o_param_operation_table_clear_template { - uint16_t Operation; - uint16_t GroupNumber; -} i2o_param_operation_table_clear_template_t; - -/* Status codes and Error Information for Parameter functions */ - -#define I2O_PARAMS_STATUS_SUCCESS 0x00 -#define I2O_PARAMS_STATUS_BAD_KEY_ABORT 0x01 -#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE 0x02 -#define I2O_PARAMS_STATUS_BUFFER_FULL 0x03 -#define I2O_PARAMS_STATUS_BUFFER_TOO_SMALL 0x04 -#define I2O_PARAMS_STATUS_FIELD_UNREADABLE 0x05 -#define I2O_PARAMS_STATUS_FIELD_UNWRITEABLE 0x06 -#define I2O_PARAMS_STATUS_INSUFFICIENT_FIELDS 0x07 -#define I2O_PARAMS_STATUS_INVALID_GROUP_ID 0x08 -#define I2O_PARAMS_STATUS_INVALID_OPERATION 0x09 -#define I2O_PARAMS_STATUS_NO_KEY_FIELD 0x0A -#define I2O_PARAMS_STATUS_NO_SUCH_FIELD 0x0B -#define I2O_PARAMS_STATUS_NON_DYNAMIC_GROUP 0x0C -#define I2O_PARAMS_STATUS_OPERATION_ERROR 0x0D -#define I2O_PARAMS_STATUS_SCALAR_ERROR 0x0E -#define I2O_PARAMS_STATUS_TABLE_ERROR 0x0F -#define I2O_PARAMS_STATUS_WRONG_GROUP_TYPE 0x10 - - -/* ************************************************************************** */ -/* GROUP Parameter Groups */ -/* ************************************************************************** */ - -/* GROUP Configuration and Operating Structures and Defines */ - -/* Groups Numbers */ - -#define I2O_UTIL_PARAMS_DESCRIPTOR_GROUP_NO 0xF000 -#define I2O_UTIL_PHYSICAL_DEVICE_TABLE_GROUP_NO 0xF001 -#define I2O_UTIL_CLAIMED_TABLE_GROUP_NO 0xF002 -#define I2O_UTIL_USER_TABLE_GROUP_NO 0xF003 -#define I2O_UTIL_PRIVATE_MESSAGE_EXTENSIONS_GROUP_NO 0xF005 -#define I2O_UTIL_AUTHORIZED_USER_TABLE_GROUP_NO 0xF006 -#define I2O_UTIL_DEVICE_IDENTITY_GROUP_NO 0xF100 -#define I2O_UTIL_DDM_IDENTITY_GROUP_NO 0xF101 -#define I2O_UTIL_USER_INFORMATION_GROUP_NO 0xF102 -#define I2O_UTIL_SGL_OPERATING_LIMITS_GROUP_NO 0xF103 -#define I2O_UTIL_SENSORS_GROUP_NO 0xF200 - -/* UTIL Group F000h - GROUP DESCRIPTORS Parameter Group */ - -#define I2O_UTIL_GROUP_PROPERTIES_GROUP_TABLE 0x01 -#define I2O_UTIL_GROUP_PROPERTIES_ROW_ADDITION 0x02 -#define I2O_UTIL_GROUP_PROPERTIES_ROW_DELETION 0x04 -#define I2O_UTIL_GROUP_PROPERTIES_CLEAR_OPERATION 0x08 - -typedef struct i2o_util_group_descriptor_table { - uint16_t GroupNumber; - uint16_t FieldCount; - uint16_t RowCount; - uint8_t Properties; - uint8_t reserved; -} i2o_util_group_descriptor_table_t; - -/* UTIL Group F001h - Physical Device Table Parameter Group */ - -typedef struct i2o_util_physical_device_table { - uint32_t AdapterID; -} i2o_util_physical_device_table_t; - -/* UTIL Group F002h - Claimed Table Parameter Group */ - -typedef struct i2o_util_claimed_table { - uint16_t ClaimedTID; -} i2o_util_claimed_table_t; - -/* UTIL Group F003h - User Table Parameter Group */ - -typedef struct i2o_util_user_table { - uint16_t Instance; - uint16_t UserTID; - uint8_t ClaimType; - uint8_t reserved1; - uint16_t reserved2; -} i2o_util_user_table_t; - -/* UTIL Group F005h - Private Message Extensions Parameter Group */ - -typedef struct i2o_util_private_message_extensions_table { - uint16_t ExtInstance; - uint16_t OrganizationID; - uint16_t XFunctionCode; -} i2o_util_private_message_extensions_table_t; - -/* UTIL Group F006h - Authorized User Table Parameter Group */ - -typedef struct i2o_util_authorized_user_table { - uint16_t AlternateTID; -} i2o_util_authorized_user_table_t; - -/* UTIL Group F100h - Device Identity Parameter Group */ - -typedef struct i2o_util_device_identity_scalar { - uint32_t ClassID; - uint16_t OwnerTID; - uint16_t ParentTID; - uint8_t VendorInfo[I2O_DEVID_VENDOR_INFO_SZ]; - uint8_t ProductInfo[I2O_DEVID_PRODUCT_INFO_SZ]; - uint8_t Description[I2O_DEVID_DESCRIPTION_SZ]; - uint8_t ProductRevLevel[I2O_DEVID_REV_LEVEL_SZ]; - uint8_t SNFormat; - uint8_t SerialNumber[I2O_MAX_SERIAL_NUMBER_SZ]; -} i2o_util_device_identity_scalar_t; - -/* UTIL Group F101h - DDM Identity Parameter Group */ - -typedef struct i2o_util_ddm_identity_scalar { - uint16_t DdmTID; - uint8_t ModuleName[I2O_MODULE_NAME_SZ]; - uint8_t ModuleRevLevel[I2O_DEVID_REV_LEVEL_SZ]; - uint8_t SNFormat; - uint8_t SerialNumber[I2O_MAX_SERIAL_NUMBER_SZ]; -} i2o_util_ddm_identity_scalar_t; - -/* UTIL Group F102h - User Information Parameter Group */ - -#define I2O_USER_DEVICE_NAME_SZ 64 -#define I2O_USER_SERVICE_NAME_SZ 64 -#define I2O_USER_PHYSICAL_LOCATION_SZ 64 - -typedef struct i2o_util_user_information_scalar { - uint8_t DeviceName[I2O_USER_DEVICE_NAME_SZ]; - uint8_t ServiceName[I2O_USER_SERVICE_NAME_SZ]; - uint8_t PhysicalLocation[I2O_USER_PHYSICAL_LOCATION_SZ]; - uint32_t InstanceNumber; -} i2o_util_user_information_scalar_t; - -/* UTIL Group F103h - SGL Operating Limits Parameter Group */ - -typedef struct i2o_util_sgl_operating_limits_scalar { - uint32_t SglChainSize; - uint32_t SglChainSizeMax; - uint32_t SglChainSizeTarget; - uint16_t SglFragCount; - uint16_t SglFragCountMax; - uint16_t SglFragCountTarget; -} i2o_util_sgl_operating_limits_scalar_t; - -/* UTIL Group F200h - Sensors Parameter Group */ - -#define I2O_SENSOR_COMPONENT_OTHER 0x00 -#define I2O_SENSOR_COMPONENT_PLANAR_LOGIC_BOARD 0x01 -#define I2O_SENSOR_COMPONENT_CPU 0x02 -#define I2O_SENSOR_COMPONENT_CHASSIS 0x03 -#define I2O_SENSOR_COMPONENT_POWER_SUPPLY 0x04 -#define I2O_SENSOR_COMPONENT_STORAGE 0x05 -#define I2O_SENSOR_COMPONENT_EXTERNAL 0x06 - -#define I2O_SENSOR_SENSOR_CLASS_ANALOG 0x00 -#define I2O_SENSOR_SENSOR_CLASS_DIGITAL 0x01 - -#define I2O_SENSOR_SENSOR_TYPE_OTHER 0x00 -#define I2O_SENSOR_SENSOR_TYPE_THERMAL 0x01 -#define I2O_SENSOR_SENSOR_TYPE_DC_VOLTAGE 0x02 -#define I2O_SENSOR_SENSOR_TYPE_AC_VOLTAGE 0x03 -#define I2O_SENSOR_SENSOR_TYPE_DC_CURRENT 0x04 -#define I2O_SENSOR_SENSOR_TYPE_AC_CURRENT 0x05 -#define I2O_SENSOR_SENSOR_TYPE_DOOR_OPEN 0x06 -#define I2O_SENSOR_SENSOR_TYPE_FAN_OPERATIONAL 0x07 - -#define I2O_SENSOR_SENSOR_STATE_NORMAL 0x00 -#define I2O_SENSOR_SENSOR_STATE_ABNORMAL 0x01 -#define I2O_SENSOR_SENSOR_STATE_UNKNOWN 0x02 -#define I2O_SENSOR_SENSOR_STATE_LOW_CAT 0x03 -#define I2O_SENSOR_SENSOR_STATE_LOW 0x04 -#define I2O_SENSOR_SENSOR_STATE_LOW_WARNING 0x05 -#define I2O_SENSOR_SENSOR_STATE_HIGH_WARNING 0x06 -#define I2O_SENSOR_SENSOR_STATE_HIGH 0x07 -#define I2O_SENSOR_SENSOR_STATE_HIGH_CAT 0x08 - -#define I2O_SENSOR_EVENT_ENABLE_STATE_CHANGE 0x0001 -#define I2O_SENSOR_EVENT_ENABLE_LOW_CATASTROPHIC 0x0002 -#define I2O_SENSOR_EVENT_ENABLE_LOW_READING 0x0004 -#define I2O_SENSOR_EVENT_ENABLE_LOW_WARNING 0x0008 -#define I2O_SENSOR_EVENT_ENABLE_CHANGE_TO_NORMAL 0x0010 -#define I2O_SENSOR_EVENT_ENABLE_HIGH_WARNING 0x0020 -#define I2O_SENSOR_EVENT_ENABLE_HIGH_READING 0x0040 -#define I2O_SENSOR_EVENT_ENABLE_HIGH_CATASTROPHIC 0x0080 - -typedef struct i2o_util_sensors_table { - uint16_t SensorInstance; - uint8_t Component; - uint16_t ComponentInstance; - uint8_t SensorClass; - uint8_t SensorType; - int8_t ScalingExponent; - int32_t ActualReading; - int32_t MinimumReading; - int32_t Low2LowCatThreshold; - int32_t LowCat2LowThreshold; - int32_t LowWarn2LowThreshold; - int32_t Low2LowWarnThreshold; - int32_t Norm2LowWarnThreshold; - int32_t LowWarn2NormThreshold; - int32_t NominalReading; - int32_t HiWarn2NormThreshold; - int32_t Norm2HiWarnThreshold; - int32_t High2HiWarnThreshold; - int32_t HiWarn2HighThreshold; - int32_t HiCat2HighThreshold; - int32_t Hi2HiCatThreshold; - int32_t MaximumReading; - uint8_t SensorState; - uint16_t EventEnable; -} i2o_util_sensors_table_t; - -/* - * ************************************************************************* - * Definitions used in Solaris for I2O Framework support. - * - * (NOTE: Current commitment level is PROJECT PRIVATE.) - * ************************************************************************* - */ - -#define I2O_MSG_SLEEP DDI_DMA_SLEEP -#define I2O_MSG_DONTWAIT DDI_DMA_DONTWAIT - -typedef void *i2o_iop_handle_t; -typedef void *i2o_msg_handle_t; - -int i2o_msg_osm_register(dev_info_t *dip, i2o_iop_handle_t *handlep); -int i2o_msg_get_lct(i2o_iop_handle_t iop, void *buf, - size_t buf_size, size_t *lct_sizep, size_t *real_sizep); -int i2o_msg_alloc(i2o_iop_handle_t iop, int (*waitfp)(caddr_t), caddr_t arg, - void **msgp, i2o_msg_handle_t *msg_handlep, - ddi_acc_handle_t *acc_handlep); -int i2o_msg_send(i2o_iop_handle_t iop, void *msg, i2o_msg_handle_t handle); -void i2o_msg_osm_unregister(i2o_iop_handle_t *iop); - -/* - * PCI Extensions to I2O Spec 1.5. - * - * (Note: Should these definitons go into pci.h?) - */ -#define PCI_I2O_BASE_CLASS 0x0E -#define PCI_I2O_SUB_CLASS 0x00 -#define PCI_I2O_PROG_CLASS0 0x00 /* no IOP interrupt */ -#define PCI_I2O_PROG_CLASS1 0x01 /* IOP interrupt supported */ - -/* Offset definitions for FIFO registers in IOP's shared memory */ - -#define PCI_IOP_INBOUND_FREELIST_FIFO 0x40 -#define PCI_IOP_INBOUND_POSTLIST_FIFO 0x40 -#define PCI_IOP_OUTBOUND_FREELIST_FIFO 0x44 -#define PCI_IOP_OUTBOUND_POSTLIST_FIFO 0x44 - -/* Offset definitions for Interrupt Control registers in IOP's shared memory */ - -#define PCI_IOP_INTR_MASK_REG 0x34 -#define PCI_IOP_INTR_STATUS_REG 0x30 - -/* Bit definitions in Interrupt Mask Register */ -#define I2O_OUTBOUND_POSTLIST_SERVICE_INTR_MASK 0x08 - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_I2OMSG_H */ diff --git a/usr/src/uts/common/sys/i2o/i2omstr.h b/usr/src/uts/common/sys/i2o/i2omstr.h deleted file mode 100644 index 3065c8c2f5..0000000000 --- a/usr/src/uts/common/sys/i2o/i2omstr.h +++ /dev/null @@ -1,920 +0,0 @@ -/* - * Copyright (c) 1998-1999 by Sun Microsystems, Inc. - * All rights reserved. - */ - -/* - * ***************************************************************************** - * - * All software on this website is made available under the following terms and - * conditions. By downloading this software, you agree to abide by these terms - * and conditions with respect to this software. - * - * I2O SIG All rights reserved. - * - * These header files are provided, pursuant to your I2O SIG membership - * agreement, free of charge on an as-is basis without warranty of any kind, - * either express or implied, including but not limited to, implied warranties - * or merchantability and fitness for a particular purpose. I2O SIG does not - * warrant that this program will meet the user's requirements or that the - * operation of these programs will be uninterrupted or error-free. - * Acceptance and use of this program constitutes the user's understanding - * that he will have no recourse to I2O SIG for any actual or consequential - * damages including, but not limited to, loss profits arising out of use - * or inability to use this program. - * - * Member is permitted to create derivative works to this header-file program. - * However, all copies of the program and its derivative works must contain the - * I2O SIG copyright notice. - * - * ***************************************************************************** - */ - -#ifndef _SYS_I2OMSTOR_H -#define _SYS_I2OMSTOR_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/i2o/i2omsg.h> /* the Base Message file */ -#include <sys/types.h> - - - -#define I2OMSTOR_REV 1_5_1 /* Header file revision string */ - - -/* - * **************************************************************************** - * - * I2OMStor.h -- I2O Random Block Storage Devices Class Message defintion - * file - * - * This file contains information presented in Chapter 6, Section 4 of - * the I2O Specification. - * - * Revision History: (Revision History tracks the revision number of the I2O - * specification) - * - * .92 - First marked revsion used for Proof of Concept. - * .93 - Change to match the rev .93 of the spec. - * .95 - Updated to Rev .95 of 2/5/96. - * 1.00 - Checked and Updated against spec version 1.00 4/9/96. - * 1.xx - Updated to the 1.x version of the I2O Specification (11/04/96). - * (RAID disk parameter group definition is not complete.) - * 1.xx - 11/06/96 1) Changed to new SGL addressing nomenclature. - * 2) Changed I2O_BSA_FLAGS reference to i2o_bsa_ctl_flags_t. - * 3) Added BSA request message definitions. - * 4) Commented out subclass and RAID request message definitions. - * 1.xx - 11/11/96 - * 1) Updated BSA Cache Control parameters group definitions. - * 1.xx - 11/13/96 - * 1) Changed messages definitions from "I20" to "I2O". - * 2) Fixed I2O_BSA_MEDIA_EJECT references. - * 3) Added "DSC" to Detailed Status Code definitions. - * 1.xx 11/15/96 - Added #pragma statments for i960. - * 1.5d 03/05/97 - Update for spec. draft version 1.5d. - * 1) Added "_BSA" designation to the three reply messages. - * 2) Added BSA_TIMEOUT DSC. - * 1.5d 04/11/97 - Corrections from review cycle: - * 1) Added reserved1 field to OPERATIONAL_CONTROL parameter group. - * 2) Added reserved2 field to ERROR_LOG parameter group. - * 3) Added reserved1 field to HIST_STATS parameter group. - * 4) Added reserved2 field to HIST_STATS parameter group. - * 5) Added reserved1 field to STORAGE_HIST_STATS parameter group. - * 6) Added reserved2 field to STORAGE_HIST_STATS parameter group. - * 7) Removed double underscore from MEDIA_INFO parameter group. - * 1.5.1 05/02/97 - Corrections from review cycle: - * 1) Change reply templates to include RetryCount field. - * 2) Add Aborted Operation reply message. - * 3) Remove #include for i2outil.h. - * 4) Add field to 32-bit align CACHE_CONTROL parameter group. - * 5) Add optional RAID parameter group definitions. - * 6) Add fields to 32-bit align REDUNDANCY parameter group. - * 7) Add fields to 32-bit align COMPONENT_SPARES parm group. - * 8) Add fields to 32-bit align ASSOCIATION parameter group. - * 9) Add revision string. - * 10) Convert tabs to spaces. - * 11) New disclaimer. - * - * **************************************************************************** - */ - -/* - * **************************************************************************** - * NOTES: - * - * Gets, reads, receives, etc. are all even numbered functions. - * Sets, writes, sends, etc. are all odd numbered functions. - * Functions that both send and receive data can be either but an attempt - * is made to use the function number that indicates the greater transfer - * amount. Functions that do not send or receive data use odd function - * numbers. - * - * Some functions are synonyms like read, receive and send, write. - * - * All common functions will have a code of less than 0x80. - * Unique functions to a class will start at 0x80. - * Executive Functions start at 0xA0. - * - * Utility Message function codes range from 0 - 0x1f - * Base Message function codes range from 0x20 - 0xfe - * Private Message function code is 0xff. - * ***************************************************************************** - */ - - - - -/* - * Random Block Storage Class specific functions - * - * Although the names are block storage class specific, the values - * assigned are common with other classes when applicable. - */ - -#define I2O_BSA_BLOCK_READ 0x30 -#define I2O_BSA_BLOCK_REASSIGN 0x71 -#define I2O_BSA_BLOCK_WRITE 0x31 -#define I2O_BSA_BLOCK_WRITE_VERIFY 0x33 -#define I2O_BSA_CACHE_FLUSH 0x37 -#define I2O_BSA_DEVICE_RESET 0x27 -#define I2O_BSA_MEDIA_EJECT 0x43 -#define I2O_BSA_MEDIA_FORMAT 0x45 -#define I2O_BSA_MEDIA_LOCK 0x49 -#define I2O_BSA_MEDIA_MOUNT 0x41 -#define I2O_BSA_MEDIA_UNLOCK 0x4B -#define I2O_BSA_MEDIA_VERIFY 0x35 -#define I2O_BSA_POWER_MANAGEMENT 0x70 -#define I2O_BSA_STATUS_CHECK 0x25 - -/* RAID Additions. */ -/* - * #define I2O_MANAGEMENT 0x81 - * #define I2O_DIAGNOSTICS 0x83 - * #define I2O_INSTRUMENTATION 0x85 - */ - -/* Detailed Status Codes for Random Block Storage operations */ - -#define I2O_BSA_DSC_SUCCESS 0x0000 -#define I2O_BSA_DSC_MEDIA_ERROR 0x0001 -#define I2O_BSA_DSC_ACCESS_ERROR 0x0002 -#define I2O_BSA_DSC_DEVICE_FAILURE 0x0003 -#define I2O_BSA_DSC_DEVICE_NOT_READY 0x0004 -#define I2O_BSA_DSC_MEDIA_NOT_PRESENT 0x0005 -#define I2O_BSA_DSC_MEDIA_LOCKED 0x0006 -#define I2O_BSA_DSC_MEDIA_FAILURE 0x0007 -#define I2O_BSA_DSC_PROTOCOL_FAILURE 0x0008 -#define I2O_BSA_DSC_BUS_FAILURE 0x0009 -#define I2O_BSA_DSC_ACCESS_VIOLATION 0x000A -#define I2O_BSA_DSC_WRITE_PROTECTED 0x000B -#define I2O_BSA_DSC_DEVICE_RESET 0x000C -#define I2O_BSA_DSC_VOLUME_CHANGED 0x000D -#define I2O_BSA_DSC_TIMEOUT 0x000E - - -/* ************************************************************************** */ - -/* Block Storage Parameter Groups */ - -/* ************************************************************************* */ - -/* Block Storage Configuration and Operating Structures and Defines */ - -/* Block Storage Parameter Groups */ - -#define I2O_BSA_DEVICE_INFO_GROUP_NO 0x0000 -#define I2O_BSA_OPERATIONAL_CONTROL_GROUP_NO 0x0001 -#define I2O_BSA_POWER_CONTROL_GROUP_NO 0x0002 -#define I2O_BSA_CACHE_CONTROL_GROUP_NO 0x0003 -#define I2O_BSA_MEDIA_INFO_GROUP_NO 0x0004 -#define I2O_BSA_ERROR_LOG_GROUP_NO 0x0005 - -/* Block Storage Optional Historical Statistics Parameter Groups */ - -#define I2O_BSA_HISTORICAL_STATS_CONTROL_GROUP_NO 0x0180 -#define I2O_BSA_STORAGE_HISTORICAL_STATS_GROUP_NO 0x0181 -#define I2O_BSA_CACHE_HISTORICAL_STATS_GROUP_NO 0x0182 - -/* Block Storage Optional RAID Disk Parameter Groups */ - -#define I2O_BSA_VOLUME_SET_INFORMATION_GROUP_NO 0x0200 -#define I2O_BSA_PROTECTED_SPACE_EXTENT_GROUP_NO 0x0201 -#define I2O_BSA_AGGREGATE_PROT_SPACE_EXT_GROUP_NO 0x0202 -#define I2O_BSA_PHYSICAL_EXTENT_GROUP_NO 0x0203 -#define I2O_BSA_AGGREGATE_PHYSICAL_EXT_GROUP_NO 0x0204 -#define I2O_BSA_REDUNDANCY_GROUP_NO 0x0205 -#define I2O_BSA_COMPONENT_SPARES_GROUP_NO 0x0206 -#define I2O_BSA_ASSOCIATION_TABLE_GROUP_NO 0x0207 - - -/* - 0000h - Device Information Parameters Group defines */ - -/* Device Type */ - -#define I2O_BSA_DEVICE_TYPE_DIRECT 0x00 -#define I2O_BSA_DEVICE_TYPE_WORM 0x04 -#define I2O_BSA_DEVICE_TYPE_CDROM 0x05 -#define I2O_BSA_DEVICE_TYPE_OPTICAL 0x07 - -/* Device Capability Support */ - -#define I2O_BSA_DEV_CAP_CACHING 0x00000001 -#define I2O_BSA_DEV_CAP_MULTI_PATH 0x00000002 -#define I2O_BSA_DEV_CAP_DYNAMIC_CAPACITY 0x00000004 -#define I2O_BSA_DEV_CAP_REMOVABLE_MEDIA 0x00000008 -#define I2O_BSA_DEV_CAP_REMOVEABLE_DEVICE 0x00000010 -#define I2O_BSA_DEV_CAP_READ_ONLY 0x00000020 -#define I2O_BSA_DEV_CAP_LOCKOUT 0x00000040 -#define I2O_BSA_DEV_CAP_BOOT_BYPASS 0x00000080 -#define I2O_BSA_DEV_CAP_COMPRESSION 0x00000100 -#define I2O_BSA_DEV_CAP_DATA_SECURITY 0x00000200 -#define I2O_BSA_DEV_CAP_RAID 0x00000400 - -/* Device States */ - -#define I2O_BSA_DEV_STATE_CACHING 0x00000001 -#define I2O_BSA_DEV_STATE_POWERED_ON 0x00000002 -#define I2O_BSA_DEV_STATE_READY 0x00000004 -#define I2O_BSA_DEV_STATE_MEDIA_LOADED 0x00000008 -#define I2O_BSA_DEV_STATE_DEVICE_LOADED 0x00000010 -#define I2O_BSA_DEV_STATE_READ_ONLY 0x00000020 -#define I2O_BSA_DEV_STATE_LOCKOUT 0x00000040 -#define I2O_BSA_DEV_STATE_BOOT_BYPASS 0x00000080 -#define I2O_BSA_DEV_STATE_COMPRESSION 0x00000100 -#define I2O_BSA_DEV_STATE_DATA_SECURITY 0x00000200 -#define I2O_BSA_DEV_STATE_RAID 0x00000400 - - -/* - 0001h - Operational Control Parameters Group defines */ - -/* No definition required */ - - -/* - 0002h - Power Control Parameters Group defines */ - -/* On Access */ - -#define I2O_BSA_POWERED_UP_ON_ACCESS 0x00000001 -#define I2O_BSA_LOAD_ON_ACCESS 0x00000002 - - -/* - 0003h - Cache Control Parameters Group defines */ - -/* Write Policy */ - -#define I2O_BSA_NO_WRITE_CACHE 0x00 -#define I2O_BSA_WRITE_TO_CACHE 0x01 -#define I2O_BSA_WRITE_THRU_CACHE 0x02 - -/* Read Policy */ - -#define I2O_BSA_NO_READ_CACHE 0x00 -#define I2O_BSA_READ_CACHE 0x01 -#define I2O_BSA_READ_AHEAD_CACHE 0x02 -#define I2O_BSA_READ_READ_AHEAD_CACHE 0x03 - -/* Error Correction */ - -#define I2O_BSA_ERR_COR_NONE 0x00 -#define I2O_BSA_ERR_COR_UNKNOWN 0x01 -#define I2O_BSA_ERR_COR_OTHER 0x02 -#define I2O_BSA_ERR_COR_PARITY 0x03 -#define I2O_BSA_ERR_COR_SINGLE_BIT_ECC 0x04 -#define I2O_BSA_ERR_COR_MULTI_BIT_ECC 0x05 - - -/* - 0004h - Media Information Parameters Group defines */ - -/* No definition required */ - - -/* - 0005h - Error Log Parameters Group defines */ - -/* No definition required */ - - -/* - 0180h - Historical Statistics Control Parameters Group defines */ - -/* Statistis Control */ - -#define I2O_BSA_STAT_CTL_STORAGE_ENABLE 0x01 -#define I2O_BSA_STAT_CTL_CACHE_ENABLE 0x02 - - -/* - 0181h - Storage Historical Statistics Parameter Group defines */ - -/* No definition required */ - - -/* - 0182h - Cache Historical Statistics Parameter Group defines */ - -/* No definition required */ - - -/* - 0200H - Volume Set Information Parameter Group defines */ - -/* No definition required */ - - -/* - 0201h - Protected Space Extent Parameter Group defines */ - -/* Data Stripe Granularity */ - -#define I2O_BSA_DATA_STRIPE_OTHER 0x00 -#define I2O_BSA_DATA_STRIPE_UNKNOWN 0x01 -#define I2O_BSA_DATA_STRIPE_BITS 0x02 -#define I2O_BSA_DATA_STRIPE_BYTES 0x03 -#define I2O_BSA_DATA_STRIPE_16BIT_WORDS 0x04 -#define I2O_BSA_DATA_STRIPE_32BIT_DWORDS 0x05 -#define I2O_BSA_DATA_STRIPE_BLOCKS 0x06 - -/* - 0202h - Aggregate Protected Space Extent Parameter Group defines */ - -/* No definition required */ - - -/* - 0203h - Physical Extent Parameter Group defines */ - -/* Granularity Unit */ - -#define I2O_BSA_GRANULARITY_OTHER 0x00 -#define I2O_BSA_GRANULARITY_UNKNOWN 0x01 -#define I2O_BSA_GRANULARITY_BITS 0x02 -#define I2O_BSA_GRANULARITY_BYTES 0x03 -#define I2O_BSA_GRANULARITY_16BIT_WORDS 0x04 -#define I2O_BSA_GRANULARITY_32BIT_DWORDS 0x05 -#define I2O_BSA_GRANULARITY_BLOCKS 0x06 - - -/* - 0204h - Aggregate Physical Extent Parameter Group defines */ - -/* No definition required */ - - -/* - 0205h - Redundancy Parameter Group defines */ - -/* Redundancy Type */ - -#define I2O_BSA_REDUNDANCY_OTHER 0x00 -#define I2O_BSA_REDUNDANCY_UNKNOWN 0x01 -#define I2O_BSA_REDUNDANCY_NONE 0x02 -#define I2O_BSA_REDUNDANCY_COPY 0x03 -#define I2O_BSA_REDUNDANCY_XOR 0x04 -#define I2O_BSA_REDUNDANCY_P_Q 0x05 -#define I2O_BSA_REDUNDANCY_S 0x06 -#define I2O_BSA_REDUNDANCY_P_S 0x07 - - -/* - 0206h - Component Spares Parameter Group defines */ - -/* Spare Functioning State */ - -#define I2O_BSA_SPARE_STATE_OTHER 0x00 -#define I2O_BSA_SPARE_STATE_UNKNOWN 0x01 -#define I2O_BSA_SPARE_STATE_INACTIVE 0x02 -#define I2O_BSA_SPARE_STATE_ACTIVE 0x03 -#define I2O_BSA_SPARE_STATE_LOAD_BALANCE 0x04 - - -/* - 0207h - Association Table Parameter Group defines */ - -/* Type */ - -#define I2O_BSA_ASSOC_TYPE_PHYSICAL 0x00 -#define I2O_BSA_ASSOC_TYPE_LOGICAL 0x01 -#define I2O_BSA_ASSOC_TYPE_LOG_TO_PHYS 0x02 -#define I2O_BSA_ASSOC_TYPE_PROTECTION 0x03 -#define I2O_BSA_ASSOC_TYPE_SPARE 0x04 -#define I2O_BSA_ASSOC_TYPE_CACHE 0x05 -#define I2O_BSA_ASSOC_TYPE_SOFTWARE 0x06 - -/* Object 1 Type */ - -#define I2O_BSA_OBJECT_1_CONTROLLER 0x00 -#define I2O_BSA_OBJECT_1_DEVICE 0x01 -#define I2O_BSA_OBJECT_1_BUS_PORT 0x02 -#define I2O_BSA_OBJECT_1_VOLUME_SET 0x03 -#define I2O_BSA_OBJECT_1_PROT_SPACE_EXT 0x04 -#define I2O_BSA_OBJECT_1_AGG_PROT_SPACE_EXT 0x05 -#define I2O_BSA_OBJECT_1_PHYSICAL_EXT 0x06 -#define I2O_BSA_OBJECT_1_AGG_PHYSICAL_EXT 0x07 -#define I2O_BSA_OBJECT_1_REDUNDANCY 0x08 -#define I2O_BSA_OBJECT_1_CACHE 0x09 -#define I2O_BSA_OBJECT_1_SOFTWARE 0x0A - -/* Object 2 Type */ - -#define I2O_BSA_OBJECT_2_CONTROLLER 0x00 -#define I2O_BSA_OBJECT_2_DEVICE 0x01 -#define I2O_BSA_OBJECT_2_BUS_PORT 0x02 -#define I2O_BSA_OBJECT_2_VOLUME_SET 0x03 -#define I2O_BSA_OBJECT_2_PROT_SPACE_EXT 0x04 -#define I2O_BSA_OBJECT_2_AGG_PROT_SPACE_EXT 0x05 -#define I2O_BSA_OBJECT_2_PHYSICAL_EXT 0x06 -#define I2O_BSA_OBJECT_2_AGG_PHYSICAL_EXT 0x07 -#define I2O_BSA_OBJECT_2_REDUNDANCY 0x08 -#define I2O_BSA_OBJECT_2_CACHE 0x09 -#define I2O_BSA_OBJECT_2_SOFTWARE 0x0A - - - - -/* Block Storage Group 0000h - Device Information Parameter Group */ - -typedef struct i2o_bsa_device_info_scalar { - uint8_t DeviceType; - uint8_t NumberOfPaths; - uint16_t PowerState; - uint32_t BlockSize; - uint64_t DeviceCapacity; - uint32_t DeviceCapabilitySupport; - uint32_t DeviceState; -} i2o_bsa_device_info_scalar_t; - - -/* Block Storage Group 0001h - Operational Control Parameter Group */ - -typedef struct i2o_bsa_operational_control_scalar { - uint8_t AutoReassign; - uint8_t ReassignTolerance; - uint8_t RetryAttempts; - uint8_t reserved1; - uint32_t ReassignSize; - uint32_t ExpectedTimeout; - uint32_t RWVTimeout; - uint32_t RWVTimeoutBase; - uint32_t TimeoutBase; - uint32_t OrderedRequestDepth; - uint32_t AtomicWriteSize; -} i2o_bsa_operational_control_scalar_t; - - -/* Block Storage Group 0002h - Power Control Parameter Group */ - -typedef struct i2o_bsa_power_control_scalar { - uint32_t PowerdownTimeout; - uint32_t OnAccess; -} i2o_bsa_power_control_scalar_t; - - -/* Block Storage Group 0003h - Cache Control Parameter Group */ - -typedef struct i2o_bsa_cache_control_scalar { - uint32_t TotalCacheSize; - uint32_t ReadCacheSize; - uint32_t WriteCacheSize; - uint8_t WritePolicy; - uint8_t ReadPolicy; - uint8_t ErrorCorrection; - uint8_t reserved1; /* Note: not in 1.5 spec. */ -} i2o_bsa_cache_control_scalar_t; - - -/* Block Storage Group 0004h - Media Information Parameter Group */ - -typedef struct i2o_bsa_media_info_scalar { - uint64_t Capacity; - uint32_t BlockSize; -} i2o_bsa_media_info_scalar_t; - - -/* Block Storage Group 0005h - Error Log Parameter Group */ - -typedef struct i2o_bsa_error_log_table { - uint16_t ErrorDataIndex; - uint8_t Function; - uint8_t RetryCount; - uint16_t DetailedErrorCode; - uint16_t reserved2; - uint64_t TimeStamp; - uint32_t UserInfo; -} i2o_bsa_error_log_table_t; - - -/* Block Storage Group 0180h - Optional Historical STATS Support/Control */ - -typedef struct i2o_bsa_hist_stats_scalar { - uint8_t StatisticsControl; - uint8_t reserved1; - uint16_t reserved2; - uint32_t StorageStatistics; - uint32_t CacheStatistics; -} i2o_bsa_hist_stats_scalar_t; - - -/* Block Storage Group 0181h - Optional Storage Historical STATS */ - -typedef struct i2o_bsa_storage_hist_stats_scalar { - uint64_t ReadCommands; - uint64_t WriteCommands; - uint8_t DataUnit; - uint8_t reserved1; - uint16_t reserved2; - uint64_t IORange1Read; - uint64_t IORange2Read; - uint64_t IORange3Read; - uint64_t IORange4Read; - uint64_t IORange1Write; - uint64_t IORange2Write; - uint64_t IORange3Write; - uint64_t IORange4Write; - uint64_t NumberSeeks; -} i2o_bsa_storage_hist_stats_scalar_t; - - -/* Block Storage Group 0182h - Optional Cache Historical STATS */ - -typedef struct i2o_bsa_cache_hist_stats_scalar { - uint64_t CacheAccess; - uint64_t CacheHit; - uint64_t PartialCacheHit; - uint64_t HitDataSize; - uint32_t ValidUsage; - uint32_t DirtyUsage; - uint32_t TimeLastFault; - uint32_t LastFaultFailure; -} i2o_bsa_cache_hist_stats_scalar_t; - - -/* Block Storage Group 0200h - Optional Volume Set Information */ - -typedef struct i2o_bsa_volume_info_scalar { - uint8_t Name[64]; - uint64_t TotalStorageCapacity; - uint64_t StripeLength; - uint64_t InterleaveDepth; -} i2o_bsa_volume_info_scalar_t; - - -/* Block Storage Group 0201h - Optional Protected Space Extent */ - -typedef struct i2o_bsa_pro_space_ext_scalar { - uint64_t StartAddress; - uint64_t NumberBlocks; - uint32_t BlockSize; - uint32_t DataStripeGranularity; - uint32_t DataStripeLength; -} i2o_bsa_pro_space_ext_scalar_t; - - -/* Block Storage Group 0202h - Optional Aggregate Protected Space Extent */ - -typedef struct i2o_bsa_agg_prot_space_ext_scalar { - uint64_t NumberBlocks; -} i2o_bsa_agg_prot_space_ext_scalar_t; - - -/* Block Storage Group 0203h - Optional Physical Extent */ - -typedef struct i2o_bsa_phys_ext_scalar { - uint64_t StartAddress; - uint64_t NumberBlocks; - uint32_t BlockSize; - uint32_t GranularityUnit; - uint64_t CheckDataInterleave; - uint64_t CheckData; - uint64_t UserData; -} i2o_bsa_phys_ext_scalar_t; - - -/* Block Storage Group 0204h - Optional Aggregate Physical Extent */ - -typedef struct i2o_bsa_agg_phys_ext_scalar { - uint64_t NumberBlocks; - uint64_t CheckData; -} i2o_bsa_agg_phys_ext_scalar_t; - - -/* Block Storage Group 0205h - Optional Redundancy Table */ - -typedef struct i2o_bsa_redundancy_scalar { - uint8_t RedundancyType; - uint8_t reserved1; /* Note: not in 1.5 spec. */ - uint16_t reserved2; /* Note: not in 1.5 spec. */ -} i2o_bsa_redundancy_scalar_t; - - -/* Block Storage Group 0206h - Optional Component Spares */ - -typedef struct i2o_bsa_component_spares_table { - uint8_t RowNumber; - uint8_t SpareType; - uint8_t ToBeSparedIndex; - uint8_t SparedIndex; - uint8_t SpareFunctioningState; - uint8_t reserved1; /* Note: not in 1.5 spec. */ - uint16_t reserved2; /* Note: not in 1.5 spec. */ -} i2o_bsa_component_spares_table_t; - - -/* Block Storage Group 0207h - Optional Association Table */ - -typedef struct i2o_bsa_association_table { - uint8_t RowNumber; - uint8_t Type; - uint8_t Object1Type; - uint8_t Object1Index; - uint8_t Object2Type; - uint8_t Object2Index; - uint16_t reserved2; /* Note: not in 1.5 spec. */ -} i2o_bsa_association_table_t; - - - -/* I2O BSA Block Storage Event Indicator Assignment */ - -#define I2O_BSA_EVENT_VOLUME_LOAD 0x00000001 -#define I2O_BSA_EVENT_VOLUME_UNLOAD 0x00000002 -#define I2O_BSA_EVENT_VOLUME_UNLOAD_REQUEST 0x00000004 -#define I2O_BSA_EVENT_CAPACITY_CHANGE 0x00000008 -#define I2O_BSA_EVENT_SCSI_SMART 0x00000010 - - - - -/* Block Storage Class Specific Message Definitions */ - - -/* I2O Block Storage Reply Message Frame Template */ - -typedef struct i2o_bsa_reply_message_frame { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t DetailedStatusCode; - uint8_t RetryCount; - uint8_t ReqStatus; -/* ReplyPayload */ -} i2o_bsa_reply_message_frame_t; - - - -/* I2O Block Storage Successful Completion Reply Message Frame */ - -typedef struct i2o_bsa_success_reply_message_frame { - i2o_bsa_reply_message_frame_t BsaReplyFrame; - uint32_t TransferCount; -} i2o_bsa_success_reply_message_frame_t; - - - -/* I2O Block Storage Aborted Operation Reply Message Frame */ - -typedef struct i2o_bsa_abort_reply_message_frame { - i2o_bsa_reply_message_frame_t BsaReplyFrame; -} i2o_bsa_abort_reply_message_frame_t; - - - -/* I2O Block Storage Progress Report Reply Message Frame */ - -typedef struct i2o_bsa_progress_reply_message_frame { - i2o_bsa_reply_message_frame_t BsaReplyFrame; - uint8_t PercentComplete; - uint8_t Reserved[3]; -} i2o_bsa_progress_reply_message_frame_t; - - -/* I2O Block Storage Error Report Reply Message Frame */ - -typedef struct i2o_bsa_error_reply_message_frame { - i2o_bsa_reply_message_frame_t BsaReplyFrame; - uint32_t TransferCount; - uint64_t LogicalByteAddress; -} i2o_bsa_error_reply_message_frame_t; - - - - -/* I2O BSA request message flag definitions */ - -/* I2O BSA Control Flags */ - -typedef uint16_t i2o_bsa_ctl_flags_t; - -#define I2O_BSA_FLAG_PROGRESS_REPORT 0x0080 - -/* I2O BSA Block Read Message Control Flags */ - -typedef uint16_t i2o_bsa_read_flags_t; -#define I2O_BSA_RD_FLAG_DONT_RETRY 0x0001 -#define I2O_BSA_RD_FLAG_SOLO 0x0002 -#define I2O_BSA_RD_FLAG_CACHE_READ 0x0004 -#define I2O_BSA_RD_FLAG_READ_PREFETCH 0x0008 -#define I2O_BSA_RD_FLAG_CACHE_DATA 0x0010 - -/* I2O BSA Block Write Message Control Flags */ - -typedef uint16_t i2o_bsa_write_flags_t; -#define I2O_BSA_WR_FLAG_DONT_RETRY 0x0001 -#define I2O_BSA_WR_FLAG_SOLO 0x0002 -#define I2O_BSA_WR_FLAG_DONT_CACHE 0x0004 -#define I2O_BSA_WR_FLAG_WRITE_THRU 0x0008 -#define I2O_BSA_WR_FLAG_WRITE_TO 0x0010 - -/* I2O BSA Device Reset Message Control Flags */ - -typedef uint16_t i2o_bsa_reset_flags_t; -#define I2O_BSA_FLAG_HARD_RESET 0x0001 - -/* I2O BSA Media Verify Message Control Flags */ - -typedef uint16_t i2o_bsa_verify_flags_t; -/* Progress Report flag definition is valid */ -#define I2O_BSA_ERROR_CORRECTION 0x0040 - - -/* I2O BSA Removeable Media Identifier values */ - -typedef uint32_t i2o_bsa_media_id_t; -#define I2O_BSA_MEDIA_ID_CURRENT_MOUNTED 0xFFFFFFFF - - -/* I2O BSA Removeable Media Load Flags */ - -typedef uint8_t i2o_bsa_load_flags_t; -#define I2O_BSA_LOAD_FLAG_MEDIA_LOCK 0x80 - - -/* I2O BSA Power Management Operation values */ - -typedef uint8_t i2o_bsa_operation_t; -#define I2O_BSA_POWER_MGT_PARTIAL_POWER_UP 0x01 -#define I2O_BSA_POWER_MGT_POWER_UP 0x02 -#define I2O_BSA_POWER_MGT_POWER_UP_LOAD 0x03 -#define I2O_BSA_POWER_MGT_QUIESCE_DEVICE 0x20 -#define I2O_BSA_POWER_MGT_PARTIAL_POWER_DOWN 0x21 -#define I2O_BSA_POWER_MGT_PARTIAL_POWER_DOWN_UNLOAD 0x22 -#define I2O_BSA_POWER_MGT_POWER_DOWN_UNLOAD 0x23 -#define I2O_BSA_POWER_MGT_POWER_DOWN_RETAIN 0x24 - - - -/* I2O BSA Block Read Message Frame */ - -typedef struct i2o_bsa_read_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_read_flags_t ControlFlags; - uint8_t TimeMultiplier; - uint8_t FetchAhead; - uint32_t TransferByteCount; - uint64_t LogicalByteAddress; - i2o_sg_element_t SGL; -} i2o_bsa_read_message_t; - - - -/* I2O BSA Block Reassign Message Frame */ - -typedef struct i2o_bsa_block_reassign_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t Reserved1; - uint8_t TimeMultiplier; - uint8_t Reserved2; - i2o_sg_element_t SGL; -} i2o_bsa_block_reassign_message_t; - - - -/* I2O BSA Block Write Message Frame */ - -typedef struct i2o_bsa_write_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_write_flags_t ControlFlags; - uint8_t TimeMultiplier; - uint8_t Reserved; - uint32_t TransferByteCount; - uint64_t LogicalByteAddress; - i2o_sg_element_t SGL; -} i2o_bsa_write_message_t; - - - -/* I2O BSA Block Write and Verify Message Frame */ - -typedef struct i2o_bsa_write_verify_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_write_flags_t ControlFlags; - uint8_t TimeMultiplier; - uint8_t Reserved; - uint32_t TransferByteCount; - uint64_t LogicalByteAddress; - i2o_sg_element_t SGL; -} i2o_bsa_write_verify_message_t; - - - -/* I2O BSA Cache Flush Message Frame */ - -typedef struct i2o_bsa_cache_flush_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_ctl_flags_t ControlFlags; - uint8_t TimeMultiplier; - uint8_t Reserved; -} i2o_bsa_cache_flush_message_t; - - - -/* I2O BSA Device Reset Message Frame */ - -typedef struct _12o_bsa_device_reset_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_reset_flags_t ControlFlags; - uint8_t TimeMultiplier; - uint8_t Reserved; -} i2o_bsa_device_reset_message_t; - - - -/* I2O BSA Media Eject for Removeable Media Message Frame */ - -typedef struct i2o_bsa_media_eject_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_media_id_t MediaIdentifier; -} i2o_bsa_media_eject_message_t; - - - -/* I2O BSA Media Lock Message Frame */ - -typedef struct i2o_bsa_media_lock_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_media_id_t MediaIdentifier; -} i2o_bsa_media_lock_message_t; - - - -/* I2O BSA Media Mount for Removeable Media Message Frame */ - -typedef struct i2o_bsa_media_mount_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_media_id_t MediaIdentifier; - i2o_bsa_load_flags_t LoadFlags; - uint8_t Reserved[3]; -} i2o_bsa_media_mount_message_t; - - - -/* I2O BSA Media Unlock Message Frame */ - -typedef struct i2o_bsa_media_unlock_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_media_id_t MediaIdentifier; -} i2o_bsa_media_unlock_message_t; - - - -/* I2O BSA Media Verify Message Frame */ - -typedef struct i2o_bsa_media_verify_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_verify_flags_t ControlFlags; - uint8_t TimeMultiplier; - uint8_t Reserved; - uint32_t ByteCount; - uint64_t LogicalByteAddress; -} i2o_bsa_media_verify_message_t; - - - -/* I2O BSA Power Management Message Frame */ - -typedef struct i2o_bsa_power_management_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - i2o_bsa_ctl_flags_t ControlFlags; - uint8_t TimeMultiplier; - uint8_t ReplyType; - i2o_bsa_operation_t Operation; -} i2o_bsa_power_management_message_t; - - - -/* I2O BSA Status Check Message Frame */ - -typedef struct i2o_bsa_status_check_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_bsa_status_check_message_t; - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_I2OMSTOR_H */ diff --git a/usr/src/uts/common/sys/i2o/i2outil.h b/usr/src/uts/common/sys/i2o/i2outil.h deleted file mode 100644 index a3bbd40267..0000000000 --- a/usr/src/uts/common/sys/i2o/i2outil.h +++ /dev/null @@ -1,391 +0,0 @@ -/* - * ********************************************************************* - * All software on this website is made available under the following - * terms and conditions. By downloading this software, you agree to - * abide by these terms and conditions with respect to this software. - * - * I2O SIG All rights reserved. - * - * These header files are provided, pursuant to your I2O SIG membership - * agreement, free of charge on an as-is basis without warranty of any - * kind, either express or implied, including but not limited to, - * implied warranties or merchantability and fitness for a particular - * purpose. I2O SIG does not warrant that this program will meet the - * user's requirements or that the operation of these programs will be - * uninterrupted or error-free. Acceptance and use of this program - * constitutes the user's understanding that he will have no recourse - * to I2O SIG for any actual or consequential damages including, but - * not limited to, loss profits arising out of use or inability to use - * this program. - * - * Member is permitted to create deriavative works to this header-file - * program. However, all copies of the program and its derivative - * works must contain the I2O SIG copyright notice. - * ******************************************************************** - */ - -/* - * ******************************************************************** - * I2OUtil.h -- I2O Utility Class Message defintion file - * - * This file contains information presented in Chapter 6 of the I2O - * Specification. - * ******************************************************************** - */ - -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_I2OUTIL_H -#define _SYS_I2OUTIL_H - -#pragma ident "%W% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#define I2OUTIL_REV 1_5_4 /* I2OUtil header file revision string */ - -#include <sys/i2o/i2omsg.h> /* Include the Base Message file */ - -/* - * ******************************************************************** - * NOTES: - * - * Gets, reads, receives, etc. are all even numbered functions. - * Sets, writes, sends, etc. are all odd numbered functions. - * Functions that both send and receive data can be either but an attempt is - * made to use the function number that indicates the greater transfer amount. - * Functions that do not send or receive data use odd function numbers. - * - * Some functions are synonyms like read, receive and send, write. - * - * All common functions will have a code of less than 0x80. - * Unique functions to a class will start at 0x80. - * Executive Functions start at 0xA0. - * - * Utility Message function codes range from 0 - 0x1f - * Base Message function codes range from 0x20 - 0xfe - * Private Message function code is 0xff. - * ******************************************************************** - */ - -/* Utility Message class functions. */ - -#define I2O_UTIL_NOP 0x00 -#define I2O_UTIL_ABORT 0x01 -#define I2O_UTIL_CLAIM 0x09 -#define I2O_UTIL_CLAIM_RELEASE 0x0B -#define I2O_UTIL_CONFIG_DIALOG 0x10 -#define I2O_UTIL_DEVICE_RESERVE 0x0D -#define I2O_UTIL_DEVICE_RELEASE 0x0F -#define I2O_UTIL_EVENT_ACKNOWLEDGE 0x14 -#define I2O_UTIL_EVENT_REGISTER 0x13 -#define I2O_UTIL_LOCK 0x17 -#define I2O_UTIL_LOCK_RELEASE 0x19 -#define I2O_UTIL_PARAMS_GET 0x06 -#define I2O_UTIL_PARAMS_SET 0x05 -#define I2O_UTIL_REPLY_FAULT_NOTIFY 0x15 - -/* ************************************************************************** */ - -/* ABORT Abort type defines. */ - -#define I2O_ABORT_TYPE_EXACT_ABORT 0x00 -#define I2O_ABORT_TYPE_FUNCTION_ABORT 0x01 -#define I2O_ABORT_TYPE_TRANSACTION_ABORT 0x02 -#define I2O_ABORT_TYPE_WILD_ABORT 0x03 -#define I2O_ABORT_TYPE_CLEAN_EXACT_ABORT 0x04 -#define I2O_ABORT_TYPE_CLEAN_FUNCTION_ABORT 0x05 -#define I2O_ABORT_TYPE_CLEAN_TRANSACTION_ABORT 0x06 -#define I2O_ABORT_TYPE_CLEAN_WILD_ABORT 0x07 - -/* UtilAbort Function Message Frame structure. */ - -typedef struct i2o_util_abort_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t reserved; - uint8_t AbortType; - uint8_t FunctionToAbort; - i2o_transaction_context_t TransactionContextToAbort; -} i2o_util_abort_message_t; - -typedef struct i2o_util_abort_reply { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t CountOfAbortedMessages; -} i2o_util_abort_reply_t; - -/* ************************************************************************** */ - -/* Claim Flag defines */ - -#define I2O_CLAIM_FLAGS_EXCLUSIVE 0x0001 /* Reserved */ -#define I2O_CLAIM_FLAGS_RESET_SENSITIVE 0x0002 -#define I2O_CLAIM_FLAGS_STATE_SENSITIVE 0x0004 -#define I2O_CLAIM_FLAGS_CAPACITY_SENSITIVE 0x0008 -#define I2O_CLAIM_FLAGS_PEER_SERVICE_DISABLED 0x0010 -#define I2O_CLAIM_FLAGS_MGMT_SERVICE_DISABLED 0x0020 - -/* Claim Type defines */ - -#define I2O_CLAIM_TYPE_PRIMARY_USER 0x01 -#define I2O_CLAIM_TYPE_AUTHORIZED_USER 0x02 -#define I2O_CLAIM_TYPE_SECONDARY_USER 0x03 -#define I2O_CLAIM_TYPE_MANAGEMENT_USER 0x04 - -/* UtilClaim Function Message Frame structure. */ - -typedef struct i2o_util_claim_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t ClaimFlags; - uint8_t reserved; - uint8_t ClaimType; -} i2o_util_claim_message_t; - -/* ************************************************************************** */ - -/* Claim Release Flag defines */ - -#define I2O_RELEASE_FLAGS_CONDITIONAL 0x0001 - -/* UtilClaimRelease Function Message Frame structure. */ - -typedef struct i2o_util_claim_release_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint16_t ReleaseFlags; - uint8_t reserved; - uint8_t ClaimType; -} i2o_util_claim_release_message_t; - -/* ************************************************************************** */ - -/* UtilConfigDialog Function Message Frame structure */ - -typedef struct i2o_util_config_dialog_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t PageNumber; - i2o_sg_element_t SGL; -} i2o_util_config_dialog_message_t; - -/* ************************************************************************** */ - -/* Event Acknowledge Function Message Frame structure */ - -typedef struct i2o_util_event_ack_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t EventIndicator; - uint32_t EventData[1]; -} i2o_util_event_ack_message_t; - -/* Event Ack Reply structure */ - -typedef struct i2o_util_event_ack_reply { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t EventIndicator; - uint32_t EventData[1]; -} i2o_util_event_ack_reply_t; - -/* ************************************************************************** */ - -/* Event Indicator Mask Flags */ - -#define I2O_EVENT_IND_STATE_CHANGE 0x80000000 -#define I2O_EVENT_IND_GENERAL_WARNING 0x40000000 -#define I2O_EVENT_IND_CONFIGURATION_FLAG 0x20000000 -/* #define I2O_EVENT_IND_RESERVE_RELEASE 0x10000000 */ -#define I2O_EVENT_IND_LOCK_RELEASE 0x10000000 -#define I2O_EVENT_IND_CAPABILITY_CHANGE 0x08000000 -#define I2O_EVENT_IND_DEVICE_RESET 0x04000000 -#define I2O_EVENT_IND_EVENT_MASK_MODIFIED 0x02000000 -#define I2O_EVENT_IND_FIELD_MODIFIED 0x01000000 -#define I2O_EVENT_IND_VENDOR_EVENT 0x00800000 -#define I2O_EVENT_IND_DEVICE_STATE 0x00400000 - -/* Event Data for generic Events */ - -#define I2O_EVENT_STATE_CHANGE_NORMAL 0x00 -#define I2O_EVENT_STATE_CHANGE_SUSPENDED 0x01 -#define I2O_EVENT_STATE_CHANGE_RESTART 0x02 -#define I2O_EVENT_STATE_CHANGE_NA_RECOVER 0x03 -#define I2O_EVENT_STATE_CHANGE_NA_NO_RECOVER 0x04 -#define I2O_EVENT_STATE_CHANGE_QUIESCE_REQUEST 0x05 -#define I2O_EVENT_STATE_CHANGE_FAILED 0x10 -#define I2O_EVENT_STATE_CHANGE_FAULTED 0x11 - -#define I2O_EVENT_GEN_WARNING_NORMAL 0x00 -#define I2O_EVENT_GEN_WARNING_ERROR_THRESHOLD 0x01 -#define I2O_EVENT_GEN_WARNING_MEDIA_FAULT 0x02 - -#define I2O_EVENT_CAPABILITY_OTHER 0x01 -#define I2O_EVENT_CAPABILITY_CHANGED 0x02 - -#define I2O_EVENT_SENSOR_STATE_CHANGED 0x01 - -/* UtilEventRegister Function Message Frame structure */ - -typedef struct i2o_util_event_register_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t EventMask; -} i2o_util_event_register_message_t; - -/* UtilEventRegister Reply structure */ - -typedef struct i2o_util_event_register_reply { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t EventIndicator; - uint32_t EventData[1]; -} i2o_util_event_register_reply_t; - -/* ************************************************************************** */ - -/* UtilLock Function Message Frame structure. */ - -typedef struct i2o_util_lock_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_util_lock_message_t; - -/* ************************************************************************** */ - -/* UtilLockRelease Function Message Frame structure. */ - -typedef struct i2o_util_lock_release_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_util_lock_release_message_t; - -/* ************************************************************************** */ - -/* UtilNOP Function Message Frame structure. */ - -typedef struct i2o_util_nop_message { - i2o_message_frame_t StdMessageFrame; -} i2o_util_nop_message_t; - -/* ************************************************************************** */ - -/* UtilParamsGet Message Frame structure. */ - -typedef struct i2o_util_params_get_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t OperationFlags; - i2o_sg_element_t SGL; -} i2o_util_params_get_message_t; - -/* ************************************************************************** */ - -/* UtilParamsSet Message Frame structure. */ - -typedef struct i2o_util_params_set_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint32_t OperationFlags; - i2o_sg_element_t SGL; -} i2o_util_params_set_message_t; - - -/* ************************************************************************** */ - -/* UtilReplyFaultNotify Message for Message Failure. */ - -#if defined(_BIT_FIELDS_LTOH) && defined(_LITTLE_ENDIAN) - -typedef struct i2o_util_reply_fault_notify_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint8_t LowestVersion; - uint8_t HighestVersion; - uint8_t Severity; - uint8_t FailureCode; - union { - struct { - uint16_t FailingIOP_ID:12; - uint16_t reserved:4; - } s; - uint16_t h1; - } u1; - uint16_t FailingHostUnitID; - uint32_t AgeLimit; -#if I2O_64BIT_CONTEXT - i2o_message_frame_t *OriginalMFA; -#else - i2o_message_frame_t *OriginalMFALowPart; - uint32_t OriginalMFAHighPart; /* Always 0000 */ -#endif -} i2o_util_reply_fault_notify_message_t; - -#define get_i2o_util_FailingIOP_ID(p, hdl) (p)->u1.s.FailingIOP_ID - -#endif - -#if defined(_BIT_FIELDS_HTOL) && defined(_BIG_ENDIAN) - -typedef struct i2o_util_reply_fault_notify_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; - uint8_t LowestVersion; - uint8_t HighestVersion; - uint8_t Severity; - uint8_t FailureCode; - union { - struct { - uint16_t reserved:4; - uint16_t FailingIOP_ID:12; - } s; - uint32_t h1; - } u1; - uint16_t FailingHostUnitID; - uint32_t AgeLimit; -#if I2O_64BIT_CONTEXT - i2o_message_frame_t *OriginalMFA; -#else - i2o_message_frame_t *OriginalMFALowPart; - uint32_t OriginalMFAHighPart; /* Always 0000 */ -#endif -} i2o_util_reply_fault_notify_message_t; - -#define get_i2o_util_FailingIOP_ID(p, hdl) \ - (ddi_get16(hdl, &(p)->u1.h1) & 0xFFF) - -#endif - -/* ************************************************************************** */ - -/* Device Reserve Function Message Frame structure. */ -/* NOTE: This was previously called the Reserve Message */ - -typedef struct i2o_util_device_reserve_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_util_device_reserve_message_t; - -/* ************************************************************************** */ - -/* Device Release Function Message Frame structure. */ -/* NOTE: This was previously called the ReserveRelease Message */ - -typedef struct i2o_util_device_release_message { - i2o_message_frame_t StdMessageFrame; - i2o_transaction_context_t TransactionContext; -} i2o_util_device_release_message_t; - -/* ************************************************************************** */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_I2OUTIL_H */ |