dman_domain.c revision 07d06da50d310a325b457d6330165aebab1e0064
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License (the "License").
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You may not use this file except in compliance with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Domain specific portion of the Starcat Management Network Driver
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Domain side function prototypes.
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int man_dr_submit_work_wait(dev_info_t *, int);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int man_dip_is_schizoxmits0_pcib(dev_info_t *, int *, int *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int man_get_eri_dev_info(dev_info_t *, man_dev_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern void man_work_add(man_workq_t *, man_work_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#if defined(DEBUG)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * man_mbox_initialized is protected by inner perimiter lock.
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = mboxsc_init(IOSRAM_KEY_SCMD, MBOXSC_MBOX_IN, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_domain_configure: failed to initialize"
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = mboxsc_init(IOSRAM_KEY_MDSC, MBOXSC_MBOX_OUT, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_domain_configure: failed to initialize"
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Build pathgroup connecting a domain to the SSC. Only called on domains
03831d35f7499c87d51205817c93e9a8d42c4baestevel * at first man_open. On the SSC, pathgroups are built by IOCTL requests
03831d35f7499c87d51205817c93e9a8d42c4baestevel * from the MAN daemon (see man_ioctl and mand(1M)).
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Locks held
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - exclusive innerperim.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If manc_ip_type indicates MAN network is not enabled
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for this domain, then lets just bailout from here as if no
03831d35f7499c87d51205817c93e9a8d42c4baestevel * devices were found.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Extract SC ethernet address from IOSRAM.
03831d35f7499c87d51205817c93e9a8d42c4baestevel mpath.mip_pg_id = 0; /* SC is always pathgroup ID 0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel mpath.mip_man_ppa = 0; /* Domain only has one ppa, 0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get list of present devices, and update man_paths[] as needed.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now activate the ethernet on the golden io board.
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < num_devs; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (mpath.mip_devs[i].mdev_exp_id == manc.manc_golden_iob)
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_CONFIG, ("man_path_discovery: returns %d\n", status));
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We are about to unload and know that there are no open
03831d35f7499c87d51205817c93e9a8d42c4baestevel * streams, so this change outside of the perimiter is ok.
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Add a work request to the inner perimeter with the new eri device info.
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* ARGSUSED */
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_DR, ("man_dr_attach: dip major = %d instance =%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_arg.a_man_ppa = 0; /* Domain only has one ppa, 0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_arg.a_pg_id = 0; /* SC is always pathgroup ID 0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Arrange to have the detaching path switched if it is active.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We will cv_wait_sig for the switch to complete if it is needed.
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = man_dr_submit_work_wait(dip, MAN_WORK_DRSWITCH);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status == EAGAIN && retries < manp->man_dr_retries) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Delay a bit and retry.
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ("man_dr_detach(switch): EAGAIN - retrying..."));
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Detaching device no longer in use, remove it from our
03831d35f7499c87d51205817c93e9a8d42c4baestevel * pathgroup.
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = man_dr_submit_work_wait(dip, MAN_WORK_DRDETACH);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status == EAGAIN && retries < manp->man_dr_retries) {
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ("man_dr_detach(detach): EAGAIN - retrying..."));
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_DR, ("man_dr_detach: returns %d", status));
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_dr_submit_work_wait(dev_info_t *dip, int work_type)
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam wp->mw_arg.a_sf_dev.mdev_major = ddi_driver_major(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_arg.a_sf_dev.mdev_ppa = ddi_get_instance(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* TBD - change to ASSERT ? */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Note that if cv_wait_sig() returns zero because a signal
03831d35f7499c87d51205817c93e9a8d42c4baestevel * was received, MAN_WFLAGS_DONE may not be set.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This will happen if man_dr_submit_work_wait() reacquires
03831d35f7499c87d51205817c93e9a8d42c4baestevel * man_lock before man_iwork() can acquire man_lock just before
03831d35f7499c87d51205817c93e9a8d42c4baestevel * signalling its work is complete.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * In this case, it is not necessary to call man_work_free()
03831d35f7499c87d51205817c93e9a8d42c4baestevel * here because it will be called by man_iwork() because
03831d35f7499c87d51205817c93e9a8d42c4baestevel * MAN_WFLAGS_CVWAITER was cleared.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Should man_iwork() obtain man_lock to signal completion,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * MAN_WFLAGS_DONE will be set which will ensure man_work_free()
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is called here.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Notify SSC of switch request and wait for response.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * There should be nothing in inbound mailbox.
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (mboxsc_getmsg(IOSRAM_KEY_SCMD, &type, &resp_cmd, &resp_tid,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: dumping message"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: sending message"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = mboxsc_putmsg(IOSRAM_KEY_MDSC, MBOXSC_MSG_REQUEST,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam req_cmd, &req_tid, sizeof (man_mbox_msg_t), &req,
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_dossc_switch: mboxsc_putmsg failed,"
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = mboxsc_getmsg(IOSRAM_KEY_SCMD, &type, &resp_cmd, &resp_tid,
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_dossc_switch: mboxsc_getmsg failed,"
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: received message"));
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " cmd/transid mismatch (%d, %d)/(%d, %d)",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam req_cmd, resp_cmd, (int)req_tid, (int)resp_tid);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_dossc_switch: failed errno == %d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Read IOSRAM info.
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = iosram_rd(IOSRAM_KEY_MANC, 0, sizeof (manc_t), (caddr_t)mcp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_get_iosram: bad magic - got(0x%x)"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " expected(0x%x)\n", mcp->manc_magic, IOSRAM_KEY_MANC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_get_iosram: version mismatch -"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " got(0x%x) expected(0x%x)\n", mcp->manc_version,
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* 0x10010102, Two */
03831d35f7499c87d51205817c93e9a8d42c4baestevel {0}, /* AF_INET6 addrs */
03831d35f7499c87d51205817c93e9a8d42c4baestevel {0}, /* AF_INET6 addrs */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* {0x8, 0x0, 0x20, 0x21, 0x44, 0x83}, Domain eaddr "two" */
03831d35f7499c87d51205817c93e9a8d42c4baestevel {0x8, 0x0, 0x20, 0x8f, 0x84, 0x63}, /* Domain eaddr "scot" */
03831d35f7499c87d51205817c93e9a8d42c4baestevel {0x8, 0x0, 0x20, 0x1f, 0xe3, 0x46}, /* SC eaddr "one" */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get IOSRAM info or release it.
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_get_iosram: bad magic - got(0x%x)"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " expected(0x%x)\n", mcp->manc_magic, IOSRAM_KEY_MANC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_get_iosram: version mismatch -"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " got(0x%x) expected(0x%x)\n", mcp->manc_version,
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* MAN_NO_IOSRAM */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find all RIOs on the IO boards for the domain. We walk all the children
03831d35f7499c87d51205817c93e9a8d42c4baestevel * of the root node looking for a PCI devinfo with a safari port ID of
03831d35f7499c87d51205817c93e9a8d42c4baestevel * 0xDC that has a child with device ID of 3. This is gauranteed to be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the network portion of the RIO by virtue of the way Starcats are
03831d35f7499c87d51205817c93e9a8d42c4baestevel * physically built.
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_find_devs: mdevpp(0x%p) golden_iob(%d)\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Hold parent busy while walking its child list.
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (man_dip_is_schizoxmits0_pcib(bus_dip, &exp_id, &xmits)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If this is XMITS0 PCI_B leaf, then the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * pci_pci bridge which is the only child,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is the parent to MAN RIO.
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam "eri_dip %s\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel ("man_find_devs: found eri maj(%d) "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ppa(%d) on expander(%d)\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_find_devs returns found = %d\n", found));
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Verify if the dip passed is an instance of 'eri' and set
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the device info in mdevp.
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_get_eri_dev_info(dev_info_t *dip, man_dev_t *mdevp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Verify if the parent is schizo(xmits)0 and pci B leaf.
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ((name = ddi_binding_name(parent_dip)) == NULL))
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This RIO could be on XMITS, so get the dip to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * XMITS PCI Leaf.
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((parent_dip = ddi_get_parent(parent_dip)) == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (((name = ddi_binding_name(parent_dip)) == NULL) ||
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam (strcmp(name, MAN_XMITS_BINDING_NAME) != 0)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (man_dip_is_schizoxmits0_pcib(parent_dip, &exp_id, &xmits) == FALSE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Make sure it is attached.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * MAN RIO is connected to SCHIZO/XMITS 0 and PCI_B Leaf.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Incase of XMITS, it is actually connected to a PCI Bridge(21154)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * which is directly connected to the PCI_B leaf of XMITS0.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function verifies if the given dip is SCHIZO/XMITS 0 and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * PCI_B Leaf. This is done as follows:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - Check the binding name to verify SCHIZO/XMITS.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - Verify the Device type to be "pci".
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - Verify the PortID to be ending with 0x1C
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - Verify the the CSR base to be 0x70.0000.
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_dip_is_schizoxmits0_pcib(dev_info_t *dip, int *exp_id, int *xmits)
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(name, MAN_XMITS_BINDING_NAME) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, MAN_DEVTYPE_PROP,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam (caddr_t)dtype, &length) == DDI_PROP_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get safari ID (DDI port ID).
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((portid = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 0,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * All schizo 0 safari IDs end in 0x1C.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * All PCI nodes "B" are at configspace 0x70.0000
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_csr_base = regbuf[0].pci_phys_mid & PCI_CONF_ADDR_MASK;
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_dip_is_eri: dip(0x%p) ndevp(0x%p)\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The network function of the RIO ASIC will always
03831d35f7499c87d51205817c93e9a8d42c4baestevel * be device 3 and function 1 ("network@3,1").
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_dip_is_eri: found eri maj(%d)"
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_dip_is_eri: returns FALSE\n"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (i_ddi_devi_attached(dip) || (state == DDI_DEVSTATE_UP)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The instance info is more important for us,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * so verify.
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki "eri 0x%p instance is not set yet", (void *)dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#if defined(DEBUG)
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tmagic: 0x%x\n", mcp->manc_magic);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tversion: 0x%x\n", mcp->manc_version);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tiob_bitmap: 0x%x\n", mcp->manc_iob_bitmap);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tgolden_iob: %d\n", mcp->manc_golden_iob);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */