66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CDDL HEADER START
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The contents of this file are subject to the terms of the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Common Development and Distribution License (the "License").
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * You may not use this file except in compliance with the License.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * or http://www.opensolaris.org/os/licensing.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * See the License for the specific language governing permissions
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * and limitations under the License.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * When distributing Covered Code, include this CDDL HEADER in each
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If applicable, add the following below this CDDL HEADER, with the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * fields enclosed by brackets "[]" replaced with your own identifying
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * information: Portions Copyright [yyyy] [name of copyright owner]
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CDDL HEADER END
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens * SiliconImage 3124/3132/3531 sata controller driver
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Few Design notes
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * I. General notes
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Even though the driver is named as si3124, it is actually meant to
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens * work with SiI3124, SiI3132 and SiI3531 controllers.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The current file si3124.c is the main driver code. The si3124reg.h
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens * holds the register definitions from SiI 3124/3132/3531 data sheets. The
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si3124var.h holds the driver specific definitions which are not
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * directly derived from data sheets.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * II. Data structures
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_ctl_state_t: This holds the driver private information for each
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * controller instance. Each of the sata ports within a single
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * controller are represented by si_port_state_t. The
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sictl_global_acc_handle and sictl_global_address map the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * controller-wide global register space and are derived from pci
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * BAR 0. The sictl_port_acc_handle and sictl_port_addr map the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * per-port register space and are derived from pci BAR 1.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_port_state_t: This holds the per port information. The siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * holds the per port mutex. The siport_pending_tags is the bit mask of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * commands posted to controller. The siport_slot_pkts[] holds the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * pending sata packets. The siport_port_type holds the device type
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * connected directly to the port while the siport_portmult_state
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * holds the similar information for the devices behind a port
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * multiplier.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_prb_t: This contains the PRB being posted to the controller.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The two SGE entries contained within si_prb_t itself are not
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * really used to hold any scatter gather entries. The scatter gather
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * list is maintained external to PRB and is linked from one
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * of the contained SGEs inside the PRB. For atapi devices, the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * first contained SGE holds the PACKET and second contained
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SGE holds the link to an external SGT. For non-atapi devices,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the first contained SGE works as link to external SGT while
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * second SGE is blank.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * external SGT tables: The external SGT tables pointed to from
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * within si_prb_t are actually abstracted as si_sgblock_t. Each
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China * si_sgblock_t contains si_dma_sg_number number of
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China * SGT tables linked in a chain. Currently this default value of
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China * SGT tables per block is at 85 as which translates
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China * to a maximum of 256 dma cookies per single dma transfer.
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China * This value can be changed through the global var: si_dma_sg_number
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China * in /etc/system, the maxium is at 21844 as which translates to 65535
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China * dma cookies per single dma transfer.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * III. Driver operation
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Command Issuing: We use the "indirect method of command issuance". The
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * PRB contains the command [and atapi PACKET] and a link to the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * external SGT chain. We write the physical address of the PRB into
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * command activation register. There are 31 command slots for
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * each port. After posting a command, we remember the posted slot &
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the sata packet in siport_pending_tags & siport_slot_pkts[]
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * respectively.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Command completion: On a successful completion, intr_command_complete()
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * receives the control. The slot_status register holds the outstanding
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * commands. Any reading of slot_status register automatically clears
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the interrupt. By comparing the slot_status register contents with
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * per port siport_pending_tags, we determine which of the previously
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * posted commands have finished.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Timeout handling: Every 5 seconds, the watchdog handler scans thru the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * pending packets. The satapkt->satapkt_hba_driver_private field is
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * overloaded with the count of watchdog cycles a packet has survived.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If a packet has not completed within satapkt->satapkt_time, it is
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * failed with error code of SATA_PKT_TIMEOUT. There is one watchdog
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * handler running for each instance of controller.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Error handling: For 3124, whenever any single command has encountered
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * an error, the whole port execution completely stalls; there is no
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * way of canceling or aborting the particular failed command. If
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the port is connected to a port multiplier, we can however RESUME
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * other non-error devices connected to the port multiplier.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The only way to recover the failed commands is to either initialize
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the port or reset the port/device. Both port initialize and reset
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * operations result in discarding any of pending commands on the port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * All such discarded commands are sent up to framework with PKT_RESET
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * satapkt_reason. The assumption is that framework [and sd] would
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * retry these commands again. The failed command itself however is
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sent up with PKT_DEV_ERROR.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Here is the implementation strategy based on SiliconImage email
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * regarding how they handle the errors for their Windows driver:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a) for DEVICEERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If the port is connected to port multiplier, then
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 1) Resume the port
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 2) Wait for all the non-failed commands to complete
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 3) Perform a Port Initialize
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If the port is not connected to port multiplier, issue
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a Port Initialize.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * b) for SDBERROR: [SDBERROR means failed command is an NCQ command]
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Handle exactly like DEVICEERROR handling.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * After the Port Initialize done, do a Read Log Extended.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * c) for SENDFISERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If the port is connected to port multiplier, then
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 1) Resume the port
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 2) Wait for all the non-failed commands to complete
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 3) Perform a Port Initialize
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If the port is not connected to port multiplier, issue
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a Device Reset.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * d) for DATAFISERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If the port was executing an NCQ command, issue a Device
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Reset.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Otherwise, follow the same error recovery as DEVICEERROR.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * e) for any other error, simply issue a Device Reset.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * To synchronize the interactions between various control flows (e.g.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * error recovery, timeout handling, si_poll_timeout, incoming flow
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * from framework etc.), the following precautions are taken care of:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a) During mopping_in_progress, no more commands are
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * accepted from the framework.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * b) While draining the port multiplier commands, we should
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * handle the possibility of any of the other waited commands
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * failing (possibly with a different error code)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Atapi handling: For atapi devices, we use the first SGE within the PRB
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to fill the scsi cdb while the second SGE points to external SGT.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Queuing: Queue management is achieved external to the driver inside sd.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Based on sata_hba_tran->qdepth and IDENTIFY data, the framework
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * enables or disables the queuing. The qdepth for si3124 is 31
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * commands.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Port Multiplier: Enumeration of port multiplier is handled during the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * controller initialization and also during the a hotplug operation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Current logic takes care of situation where a port multiplier
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is hotplugged into a port which had a cdisk connected previously
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * and vice versa.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Register poll timeouts: Currently most of poll timeouts on register
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * reads is set to 0.5 seconds except for a value of 10 seconds
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * while reading the device signature. [Such a big timeout values
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * for device signature were found needed during cold reboots
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * for devices behind port multiplier].
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * IV. Known Issues
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 1) Currently the atapi packet length is hard coded to 12 bytes
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This is wrong. The framework should determine it just like they
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * determine ad_cdb_len in legacy atapi.c. It should even reject
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * init_pkt() for greater CDB lengths. See atapi.c. Revisit this
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * in 2nd phase of framework project.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 2) Do real REQUEST SENSE command instead of faking for ATAPI case.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#include <sys/note.h>
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#include <sys/scsi/scsi.h>
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#include <sys/pci.h>
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#include <sys/sata/sata_hba.h>
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#include <sys/sata/adapters/si3124/si3124reg.h>
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#include <sys/sata/adapters/si3124/si3124var.h>
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek#include <sys/sdt.h>
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan/*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * FMA header files
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan#include <sys/ddifm.h>
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan#include <sys/fm/protocol.h>
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan#include <sys/fm/util.h>
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan#include <sys/fm/io/ddi.h>
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Function prototypes for driver entry points
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_attach(dev_info_t *, ddi_attach_cmd_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_detach(dev_info_t *, ddi_detach_cmd_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing Chinastatic int si_power(dev_info_t *, int, int);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing Chinastatic int si_quiesce(dev_info_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Function prototypes for SATA Framework interfaces
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_register_sata_hba_tran(si_ctl_state_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_unregister_sata_hba_tran(si_ctl_state_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_tran_probe_port(dev_info_t *, sata_device_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_tran_start(dev_info_t *, sata_pkt_t *spkt);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_tran_abort(dev_info_t *, sata_pkt_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_tran_reset_dport(dev_info_t *, sata_device_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_tran_hotplug_port_activate(dev_info_t *, sata_device_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_tran_hotplug_port_deactivate(dev_info_t *, sata_device_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Local function prototypes
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_alloc_port_state(si_ctl_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_dealloc_port_state(si_ctl_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_alloc_sgbpool(si_ctl_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_dealloc_sgbpool(si_ctl_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_alloc_prbpool(si_ctl_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_dealloc_prbpool(si_ctl_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_find_dev_signature(si_ctl_state_t *, si_port_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_poll_cmd(si_ctl_state_t *, si_port_state_t *, int, int,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_claim_free_slot(si_ctl_state_t *, si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_deliver_satapkt(si_ctl_state_t *, si_port_state_t *, int,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_initialize_controller(si_ctl_state_t *);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesekstatic void si_deinitialize_controller(si_ctl_state_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_init_port(si_ctl_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_enumerate_port_multiplier(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_read_portmult_reg(si_ctl_state_t *, si_port_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int, int, int, uint32_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_write_portmult_reg(si_ctl_state_t *, si_port_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int, int, int, uint32_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_set_sense_data(sata_pkt_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic uint_t si_intr(caddr_t, caddr_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_command_complete(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Loganstatic void si_schedule_intr_command_error(si_ctl_state_t *,
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_port_state_t *, int);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Loganstatic void si_do_intr_command_error(void *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_command_error(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_error_recovery_DEVICEERROR(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_error_recovery_SDBERROR(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_error_recovery_DATAFISERROR(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_error_recovery_SENDFISERROR(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_error_recovery_default(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic uint8_t si_read_log_ext(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_log_error_message(si_ctl_state_t *, int, uint32_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_port_ready(si_ctl_state_t *, si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_pwr_change(si_ctl_state_t *, si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_phy_ready_change(si_ctl_state_t *, si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_comwake_rcvd(si_ctl_state_t *, si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_unrecognised_fis(si_ctl_state_t *, si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_dev_xchanged(si_ctl_state_t *, si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_decode_err_threshold(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_crc_err_threshold(si_ctl_state_t *, si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_handshake_err_threshold(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_intr_set_devbits_notify(si_ctl_state_t *, si_port_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_enable_port_interrupts(si_ctl_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_enable_all_interrupts(si_ctl_state_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_disable_port_interrupts(si_ctl_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_disable_all_interrupts(si_ctl_state_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void fill_dev_sregisters(si_ctl_state_t *, int, sata_device_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_add_legacy_intrs(si_ctl_state_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_add_msi_intrs(si_ctl_state_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_rem_intrs(si_ctl_state_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_reset_dport_wait_till_ready(si_ctl_state_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *, int, int);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing Chinastatic int si_clear_port(si_ctl_state_t *, int);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Loganstatic void si_schedule_port_initialize(si_ctl_state_t *,
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_port_state_t *, int);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Loganstatic void si_do_initialize_port(void *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_initialize_port_wait_till_ready(si_ctl_state_t *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_timeout_pkts(si_ctl_state_t *, si_port_state_t *, int, uint32_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void si_watchdog_handler(si_ctl_state_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan/*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * FMA Prototypes
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic void si_fm_init(si_ctl_state_t *);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic void si_fm_fini(si_ctl_state_t *);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic int si_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic int si_check_acc_handle(ddi_acc_handle_t);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic int si_check_dma_handle(ddi_dma_handle_t);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic int si_check_ctl_handles(si_ctl_state_t *);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic int si_check_port_handles(si_port_state_t *);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic void si_fm_ereport(si_ctl_state_t *, char *, char *);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Ramastatic void si_log(si_ctl_state_t *, si_port_state_t *, char *, ...);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesekstatic void si_copy_out_regs(sata_cmd_t *, si_ctl_state_t *, uint8_t, uint8_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DMA attributes for the data buffer
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic ddi_dma_attr_t buffer_dma_attr = {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf DMA_ATTR_V0, /* dma_attr_version */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0, /* dma_attr_addr_lo: lowest bus address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 1, /* dma_attr_align: single byte aligned */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 1, /* dma_attr_burstsizes */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 1, /* dma_attr_minxfer */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0xffffffffull, /* dma_attr_seg */
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China SI_DEFAULT_SGL_LENGTH, /* dma_attr_sgllen */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 512, /* dma_attr_granular */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0, /* dma_attr_flags */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf};
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DMA attributes for incore RPB and SGT pool
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic ddi_dma_attr_t prb_sgt_dma_attr = {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf DMA_ATTR_V0, /* dma_attr_version */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0, /* dma_attr_addr_lo: lowest bus address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 8, /* dma_attr_align: quad word aligned */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 1, /* dma_attr_burstsizes */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 1, /* dma_attr_minxfer */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0xffffffffull, /* dma_attr_seg */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 1, /* dma_attr_sgllen */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 1, /* dma_attr_granular */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0, /* dma_attr_flags */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf};
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* Device access attributes */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic ddi_device_acc_attr_t accattr = {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_DEVICE_ATTR_V1,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf DDI_STRUCTURE_LE_ACC,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_STRICTORDER_ACC,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_DEFAULT_ACC
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf};
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic struct dev_ops sictl_dev_ops = {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf DEVO_REV, /* devo_rev */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0, /* refcnt */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_getinfo, /* info */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf nulldev, /* identify */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf nulldev, /* probe */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_attach, /* attach */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_detach, /* detach */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf nodev, /* no reset */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (struct cb_ops *)0, /* driver operations */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf NULL, /* bus operations */
193974072f41a843678abf5f61979c748687e66bSherry Moore si_power, /* power */
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China si_quiesce, /* devo_quiesce */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf};
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic sata_tran_hotplug_ops_t si_tran_hotplug_ops = {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SATA_TRAN_HOTPLUG_OPS_REV_1,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_tran_hotplug_port_activate,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_tran_hotplug_port_deactivate
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf};
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_watchdog_timeout = 5; /* 5 seconds */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int si_watchdog_tick;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfextern struct mod_ops mod_driverops;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic struct modldrv modldrv = {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf &mod_driverops, /* driverops */
193974072f41a843678abf5f61979c748687e66bSherry Moore "si3124 driver",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf &sictl_dev_ops, /* driver ops */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf};
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic struct modlinkage modlinkage = {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf MODREV_1,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf &modldrv,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf NULL
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf};
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* The following are needed for si_log() */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic kmutex_t si_log_mutex;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Ramastatic char si_log_buf[SI_LOGBUF_LEN];
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Ramauint32_t si_debug_flags =
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_ERRS|SIDBG_INIT|SIDBG_EVENT|SIDBG_TIMEOUT|SIDBG_RESET;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int is_msi_supported = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China/*
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China * The below global variables are tunable via /etc/system
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China *
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China * si_dma_sg_number
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China */
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing Chinaint si_dma_sg_number = SI_DEFAULT_SGT_TABLES_PER_PRB;
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* Opaque state pointer to be initialized by ddi_soft_state_init() */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void *si_statep = NULL;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si3124 module initialization.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_init(void)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int error;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf error = ddi_soft_state_init(&si_statep, sizeof (si_ctl_state_t), 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (error != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (error);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_init(&si_log_mutex, NULL, MUTEX_DRIVER, NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((error = sata_hba_init(&modlinkage)) != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_destroy(&si_log_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_soft_state_fini(&si_statep);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (error);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf error = mod_install(&modlinkage);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (error != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_fini(&modlinkage);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_destroy(&si_log_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_soft_state_fini(&si_statep);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (error);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_watchdog_tick = drv_usectohz((clock_t)si_watchdog_timeout * 1000000);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (error);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si3124 module uninitialize.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_fini(void)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int error;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf error = mod_remove(&modlinkage);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (error != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (error);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Remove the resources allocated in _init(). */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_fini(&modlinkage);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_destroy(&si_log_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_soft_state_fini(&si_statep);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (error);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * _info entry point
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_info(struct modinfo *modinfop)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (mod_info(&modlinkage, modinfop));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The attach entry point for dev_ops.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We initialize the controller, initialize the soft state, register
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the interrupt handlers and then register ourselves with sata framework.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int instance;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int attach_state;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int intr_types;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_device_t sdevice;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG(SIDBG_ENTRY, "si_attach enter", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf instance = ddi_get_instance(dip);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf attach_state = ATTACH_PROGRESS_NONE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (cmd) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case DDI_ATTACH:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Allocate si_softc. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf status = ddi_soft_state_zalloc(si_statep, instance);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (status != DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf goto err_out;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, instance);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_devinfop = dip;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf attach_state |= ATTACH_PROGRESS_STATEP_ALLOC;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /* Initialize FMA */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_ctlp->fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, dip,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_fm_init(si_ctlp);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan attach_state |= ATTACH_PROGRESS_INIT_FMA;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Configure pci config space handle. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf status = pci_config_setup(dip, &si_ctlp->sictl_pci_conf_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (status != DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf goto err_out;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_devid =
193974072f41a843678abf5f61979c748687e66bSherry Moore pci_config_get16(si_ctlp->sictl_pci_conf_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCI_CONF_DEVID);
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens switch (si_ctlp->sictl_devid) {
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens case SI3124_DEV_ID:
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens si_ctlp->sictl_num_ports = SI3124_MAX_PORTS;
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens break;
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens case SI3132_DEV_ID:
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens si_ctlp->sictl_num_ports = SI3132_MAX_PORTS;
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens break;
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens case SI3531_DEV_ID:
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens si_ctlp->sictl_num_ports = SI3531_MAX_PORTS;
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens break;
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens default:
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens /*
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens * Driver should not have attatched if device
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens * ID is not already known and is supported.
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens */
b74cec98319cdf0854be09126da89ba80d5baa2eCharles Stephens goto err_out;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf attach_state |= ATTACH_PROGRESS_CONF_HANDLE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now map the bar0; the bar0 contains the global registers. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf status = ddi_regs_map_setup(dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCI_BAR0,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&si_ctlp->sictl_global_addr,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore &accattr,
193974072f41a843678abf5f61979c748687e66bSherry Moore &si_ctlp->sictl_global_acc_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (status != DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf goto err_out;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf attach_state |= ATTACH_PROGRESS_BAR0_MAP;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now map bar1; the bar1 contains the port registers. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf status = ddi_regs_map_setup(dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCI_BAR1,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&si_ctlp->sictl_port_addr,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore &accattr,
193974072f41a843678abf5f61979c748687e66bSherry Moore &si_ctlp->sictl_port_acc_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (status != DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf goto err_out;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf attach_state |= ATTACH_PROGRESS_BAR1_MAP;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Disable all the interrupts before adding interrupt
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * handler(s). The interrupts shall be re-enabled selectively
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * out of si_init_port().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_disable_all_interrupts(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Get supported interrupt types. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_intr_get_supported_types(dip, &intr_types)
193974072f41a843678abf5f61979c748687e66bSherry Moore != DDI_SUCCESS) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "ddi_intr_get_supported_types failed", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf goto err_out;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "ddi_intr_get_supported_types() returned: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore intr_types);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (is_msi_supported && (intr_types & DDI_INTR_TYPE_MSI)) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "Using MSI interrupt type", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Try MSI first, but fall back to legacy if MSI
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * attach fails.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_add_msi_intrs(si_ctlp) == DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_intr_type = DDI_INTR_TYPE_MSI;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf attach_state |= ATTACH_PROGRESS_INTR_ADDED;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "MSI interrupt setup done", NULL);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama } else {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "MSI registration failed "
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "will try Legacy interrupts", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(attach_state & ATTACH_PROGRESS_INTR_ADDED) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (intr_types & DDI_INTR_TYPE_FIXED)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Either the MSI interrupt setup has failed or only
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * fixed interrupts are available on the system.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "Using Legacy interrupt type", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_add_legacy_intrs(si_ctlp) == DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_intr_type = DDI_INTR_TYPE_FIXED;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf attach_state |= ATTACH_PROGRESS_INTR_ADDED;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "Legacy interrupt setup done", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "legacy interrupt setup failed", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf goto err_out;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(attach_state & ATTACH_PROGRESS_INTR_ADDED)) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si3124: No interrupts registered", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf goto err_out;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Initialize the mutex. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_init(&si_ctlp->sictl_mutex, NULL, MUTEX_DRIVER,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)(uintptr_t)si_ctlp->sictl_intr_pri);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf attach_state |= ATTACH_PROGRESS_MUTEX_INIT;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Initialize the controller and driver core.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags |= SI_ATTACH;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf status = si_initialize_controller(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags &= ~SI_ATTACH;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (status) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf goto err_out;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf attach_state |= ATTACH_PROGRESS_HW_INIT;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_register_sata_hba_tran(si_ctlp)) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si3124: setting sata hba tran failed", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf goto err_out;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_timeout_id = timeout(
193974072f41a843678abf5f61979c748687e66bSherry Moore (void (*)(void *))si_watchdog_handler,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)si_ctlp, si_watchdog_tick);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_power_level = PM_LEVEL_D0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case DDI_RESUME:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, instance);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf status = si_initialize_controller(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (status) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_timeout_id = timeout(
193974072f41a843678abf5f61979c748687e66bSherry Moore (void (*)(void *))si_watchdog_handler,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)si_ctlp, si_watchdog_tick);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) pm_power_has_changed(dip, 0, PM_LEVEL_D0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Notify SATA framework about RESUME. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_hba_attach(si_ctlp->sictl_devinfop,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_sata_hba_tran,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_RESUME) != DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Notify the "framework" that it should reprobe ports to see
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * if any device got changed while suspended.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bzero((void *)&sdevice, sizeof (sata_device_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_event_notify(dip, &sdevice,
193974072f41a843678abf5f61979c748687e66bSherry Moore SATA_EVNT_PWR_LEVEL_CHANGED);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT|SIDBG_EVENT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "sending event up: SATA_EVNT_PWR_LEVEL_CHANGED", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) pm_idle_component(si_ctlp->sictl_devinfop, 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_power_level = PM_LEVEL_D0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf default:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlferr_out:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (attach_state & ATTACH_PROGRESS_HW_INIT) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags |= SI_DETACH;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We want to set SI_DETACH to deallocate all memory */
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek si_deinitialize_controller(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags &= ~SI_DETACH;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (attach_state & ATTACH_PROGRESS_MUTEX_INIT) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_destroy(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (attach_state & ATTACH_PROGRESS_INTR_ADDED) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_rem_intrs(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (attach_state & ATTACH_PROGRESS_BAR1_MAP) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_regs_map_free(&si_ctlp->sictl_port_acc_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (attach_state & ATTACH_PROGRESS_BAR0_MAP) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_regs_map_free(&si_ctlp->sictl_global_acc_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (attach_state & ATTACH_PROGRESS_CONF_HANDLE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf pci_config_teardown(&si_ctlp->sictl_pci_conf_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (attach_state & ATTACH_PROGRESS_INIT_FMA) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_fm_fini(si_ctlp);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (attach_state & ATTACH_PROGRESS_STATEP_ALLOC) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_soft_state_free(si_statep, instance);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The detach entry point for dev_ops.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We undo the things we did in si_attach().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int instance;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG(SIDBG_ENTRY, "si_detach enter", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf instance = ddi_get_instance(dip);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, instance);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (cmd) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case DDI_DETACH:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* disable the interrupts for an uninterrupted detach */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_disable_all_interrupts(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* unregister from the sata framework. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_unregister_sata_hba_tran(si_ctlp) != SI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_enable_all_interrupts(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* now cancel the timeout handler. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) untimeout(si_ctlp->sictl_timeout_id);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek /* de-initialize the controller. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags |= SI_DETACH;
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek si_deinitialize_controller(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags &= ~SI_DETACH;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* destroy any mutexes */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_destroy(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* remove the interrupts */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_rem_intrs(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* remove the reg maps. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_regs_map_free(&si_ctlp->sictl_port_acc_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_regs_map_free(&si_ctlp->sictl_global_acc_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf pci_config_teardown(&si_ctlp->sictl_pci_conf_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /* deinit FMA */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_fm_fini(si_ctlp);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* free the soft state. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_soft_state_free(si_statep, instance);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case DDI_SUSPEND:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Inform SATA framework */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_hba_detach(dip, cmd) != DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Device needs to be at full power in case it is needed to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * handle dump(9e) to save CPR state after DDI_SUSPEND
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * completes. This is OK since presumably power will be
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * removed anyways. No outstanding transactions should be
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek * on the controller since the children are already quiesced.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If any ioctls/cfgadm support is added that touches
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * hardware, those entry points will need to check for
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * suspend and then block or return errors until resume.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (pm_busy_component(si_ctlp->sictl_devinfop, 0) ==
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) pm_raise_power(si_ctlp->sictl_devinfop, 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore PM_LEVEL_D0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek si_deinitialize_controller(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) untimeout(si_ctlp->sictl_timeout_id);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: DDI_SUSPEND",
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama instance);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf default:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_power(dev_info_t *dip, int component, int level)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ARGUNUSED(component))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int instance = ddi_get_instance(dip);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int rval = DDI_SUCCESS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int old_level;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_device_t sdevice;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, instance);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_ctlp == NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ENTRY, si_ctlp, "si_power enter", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf old_level = si_ctlp->sictl_power_level;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (level) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case PM_LEVEL_D0: /* fully on */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf pci_config_put16(si_ctlp->sictl_pci_conf_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore PM_CSR(si_ctlp->sictl_devid), PCI_PMCSR_D0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(drv_usectohz(10000));
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_power_level = PM_LEVEL_D0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) pci_restore_config_regs(si_ctlp->sictl_devinfop);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_POWER, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si3124%d: turning power ON. old level %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore instance, old_level);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If called from attach, just raise device power,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * restore config registers (if they were saved
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * from a previous detach that lowered power),
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * and exit.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_ctlp->sictl_flags & SI_ATTACH)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_initialize_controller(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_timeout_id = timeout(
193974072f41a843678abf5f61979c748687e66bSherry Moore (void (*)(void *))si_watchdog_handler,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)si_ctlp, si_watchdog_tick);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bzero((void *)&sdevice, sizeof (sata_device_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_event_notify(
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_sata_hba_tran->sata_tran_hba_dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore &sdevice, SATA_EVNT_PWR_LEVEL_CHANGED);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_EVENT|SIDBG_POWER, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "sending event up: PWR_LEVEL_CHANGED", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case PM_LEVEL_D3: /* fully off */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(si_ctlp->sictl_flags & SI_DETACH)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) untimeout(si_ctlp->sictl_timeout_id);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek si_deinitialize_controller(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_power_level = PM_LEVEL_D3;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) pci_save_config_regs(si_ctlp->sictl_devinfop);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf pci_config_put16(si_ctlp->sictl_pci_conf_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore PM_CSR(si_ctlp->sictl_devid), PCI_PMCSR_D3HOT);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: turning power OFF. "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "old level %d", instance, old_level);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf default:
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: turning power OFF. "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "old level %d", instance, old_level);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rval = DDI_FAILURE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (rval);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The info entry point for dev_ops.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf void *arg,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf void **result)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ARGUNUSED(dip))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int instance;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf dev_t dev;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf dev = (dev_t)arg;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf instance = getminor(dev);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (infocmd) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case DDI_INFO_DEVT2DEVINFO:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, instance);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_ctlp != NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *result = si_ctlp->sictl_devinfop;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *result = NULL;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case DDI_INFO_DEVT2INSTANCE:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *(int *)result = instance;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf default:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Registers the si3124 with sata framework.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_register_sata_hba_tran(si_ctl_state_t *si_ctlp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct sata_hba_tran *sata_hba_tran;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ENTRY, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_register_sata_hba_tran entry", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Allocate memory for the sata_hba_tran */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran = kmem_zalloc(sizeof (sata_hba_tran_t), KM_SLEEP);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_hba_rev = SATA_TRAN_HBA_REV;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_hba_dip = si_ctlp->sictl_devinfop;
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China if (si_dma_sg_number > SI_MAX_SGT_TABLES_PER_PRB) {
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China si_dma_sg_number = SI_MAX_SGT_TABLES_PER_PRB;
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China } else if (si_dma_sg_number < SI_MIN_SGT_TABLES_PER_PRB) {
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China si_dma_sg_number = SI_MIN_SGT_TABLES_PER_PRB;
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China }
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China if (si_dma_sg_number != SI_DEFAULT_SGT_TABLES_PER_PRB) {
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China buffer_dma_attr.dma_attr_sgllen = SGE_LENGTH(si_dma_sg_number);
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_hba_dma_attr = &buffer_dma_attr;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_hba_num_cports = si_ctlp->sictl_num_ports;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_hba_features_support = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_hba_qdepth = SI_NUM_SLOTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_probe_port = si_tran_probe_port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_start = si_tran_start;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_abort = si_tran_abort;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_reset_dport = si_tran_reset_dport;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_selftest = NULL;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_hotplug_ops = &si_tran_hotplug_ops;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran->sata_tran_ioctl = NULL;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Attach it to SATA framework */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_hba_attach(si_ctlp->sictl_devinfop, sata_hba_tran, DDI_ATTACH)
193974072f41a843678abf5f61979c748687e66bSherry Moore != DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_sata_hba_tran = sata_hba_tran;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Unregisters the si3124 with sata framework.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_unregister_sata_hba_tran(si_ctl_state_t *si_ctlp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Detach from the SATA framework. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_hba_detach(si_ctlp->sictl_devinfop, DDI_DETACH) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Deallocate sata_hba_tran. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free((void *)si_ctlp->sictl_sata_hba_tran,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (sata_hba_tran_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_sata_hba_tran = NULL;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Called by sata framework to probe a port. We return the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * cached information from a previous hardware probe.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The actual hardware probing itself was done either from within
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_initialize_controller() during the driver attach or
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * from a phy ready change interrupt handler.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_tran_probe_port(dev_info_t *dip, sata_device_t *sd)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t cport = sd->satadev_addr.cport;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t pmport = sd->satadev_addr.pmport;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t qual = sd->satadev_addr.qual;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t port_type;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portmult_state_t *si_portmultp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ENTRY, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_tran_probe_port: cport: 0x%x, pmport: 0x%x, qual: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore cport, pmport, qual);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (cport >= SI_MAX_PORTS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sd->satadev_type = SATA_DTYPE_NONE;
4372d277de71fc7c19cb9f41df9b8757b34e2cc5pawelw sd->satadev_state = SATA_STATE_UNKNOWN; /* invalid port */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[cport];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp == NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sd->satadev_type = SATA_DTYPE_NONE;
4372d277de71fc7c19cb9f41df9b8757b34e2cc5pawelw sd->satadev_state = SATA_STATE_UNKNOWN;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (qual == SATA_ADDR_PMPORT) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (pmport >= si_portp->siport_portmult_state.sipm_num_ports) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sd->satadev_type = SATA_DTYPE_NONE;
4372d277de71fc7c19cb9f41df9b8757b34e2cc5pawelw sd->satadev_state = SATA_STATE_UNKNOWN;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portmultp = &si_portp->siport_portmult_state;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_type = si_portmultp->sipm_port_type[pmport];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_type = si_portp->siport_port_type;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (port_type) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case PORT_TYPE_DISK:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sd->satadev_type = SATA_DTYPE_ATADISK;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case PORT_TYPE_ATAPI:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sd->satadev_type = SATA_DTYPE_ATAPICD;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case PORT_TYPE_MULTIPLIER:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sd->satadev_type = SATA_DTYPE_PMULT;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sd->satadev_add_info =
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp->siport_portmult_state.sipm_num_ports;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case PORT_TYPE_UNKNOWN:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sd->satadev_type = SATA_DTYPE_UNKNOWN;
4372d277de71fc7c19cb9f41df9b8757b34e2cc5pawelw break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf default:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* we don't support any other device types. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sd->satadev_type = SATA_DTYPE_NONE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
4372d277de71fc7c19cb9f41df9b8757b34e2cc5pawelw sd->satadev_state = SATA_STATE_READY;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (qual == SATA_ADDR_PMPORT) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
193974072f41a843678abf5f61979c748687e66bSherry Moore pmport, PSCR_REG0, &sd->satadev_scr.sstatus);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
193974072f41a843678abf5f61979c748687e66bSherry Moore pmport, PSCR_REG1, &sd->satadev_scr.serror);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
193974072f41a843678abf5f61979c748687e66bSherry Moore pmport, PSCR_REG2, &sd->satadev_scr.scontrol);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
193974072f41a843678abf5f61979c748687e66bSherry Moore pmport, PSCR_REG3, &sd->satadev_scr.sactive);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf fill_dev_sregisters(si_ctlp, cport, sd);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(si_portp->siport_active)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Since we are implementing the port deactivation
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * in software only, we need to fake a valid value
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * for sstatus when the device is in deactivated state.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SSTATUS_SET_DET(sd->satadev_scr.sstatus,
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_DET_PHYOFFLINE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SSTATUS_SET_IPM(sd->satadev_scr.sstatus,
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_IPM_NODEV_NOPHY);
4372d277de71fc7c19cb9f41df9b8757b34e2cc5pawelw sd->satadev_state = SATA_PSTATE_SHUTDOWN;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Called by sata framework to transport a sata packet down stream.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The actual work of building the FIS & transporting it to the hardware
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is done out of the subroutine si_deliver_satapkt().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_tran_start(dev_info_t *dip, sata_pkt_t *spkt)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t cport;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cport = spkt->satapkt_device.satadev_addr.cport;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[cport];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ENTRY, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_tran_start entry", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore !si_portp->siport_active) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_intr_phy_ready_change() may have rendered it to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * PORT_TYPE_NODEV. cfgadm operation may have rendered
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * it inactive.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf fill_dev_sregisters(si_ctlp, cport, &spkt->satapkt_device);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_TRAN_PORT_ERROR);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
c03acfcad7780db4ddf763511a82026680b3b2c1ls if (spkt->satapkt_cmd.satacmd_flags.sata_clear_dev_reset) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_reset_in_progress = 0;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_RESET, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_tran_start clearing the "
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "reset_in_progress for port", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_reset_in_progress &&
193974072f41a843678abf5f61979c748687e66bSherry Moore ! spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset &&
193974072f41a843678abf5f61979c748687e66bSherry Moore ! ddi_in_panic()) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spkt->satapkt_reason = SATA_PKT_BUSY;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_RESET, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_tran_start returning BUSY while "
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "reset in progress for port", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_TRAN_BUSY);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan if (si_portp->mopping_in_progress > 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spkt->satapkt_reason = SATA_PKT_BUSY;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_RESET, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_tran_start returning BUSY while "
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "mopping in progress for port", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_TRAN_BUSY);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((slot = si_deliver_satapkt(si_ctlp, si_portp, cport, spkt))
193974072f41a843678abf5f61979c748687e66bSherry Moore == SI_FAILURE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_tran_start returning QUEUE_FULL",
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_TRAN_QUEUE_FULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (spkt->satapkt_op_mode & (SATA_OPMODE_POLLING|SATA_OPMODE_SYNCH)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* we need to poll now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_poll_cmd(si_ctlp, si_portp, cport, slot, spkt);
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan /*
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan * The command has completed, and spkt will be freed by the
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan * sata module, so don't keep a pointer to it lying around.
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan */
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan si_portp->siport_slot_pkts[slot] = NULL;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_TRAN_ACCEPTED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#define SENDUP_PACKET(si_portp, satapkt, reason) \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (satapkt) { \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if ((satapkt->satapkt_cmd.satacmd_cmd_reg == \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SATAC_WRITE_FPDMA_QUEUED) || \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan (satapkt->satapkt_cmd.satacmd_cmd_reg == \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SATAC_READ_FPDMA_QUEUED)) { \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_portp->siport_pending_ncq_count--; \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan } \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt->satapkt_reason = reason; \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We set the satapkt_reason in both synch and \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * non-synch cases. \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */ \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (!(satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) && \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan satapkt->satapkt_comp) { \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan mutex_exit(&si_portp->siport_mutex); \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan (*satapkt->satapkt_comp)(satapkt); \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan mutex_enter(&si_portp->siport_mutex); \
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan } \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Mopping is necessitated because of the si3124 hardware limitation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The only way to recover from errors or to abort a command is to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * reset the port/device but such a reset also results in throwing
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * away all the unfinished pending commands.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * A port or device is reset in four scenarios:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a) some commands failed with errors
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * b) or we need to timeout some commands
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * c) or we need to abort some commands
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * d) or we need reset the port at the request of sata framework
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * In all these scenarios, we need to send any pending unfinished
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * commands up to sata framework.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan * WARNING!!! siport_mutex should be acquired before the function is called.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_mop_commands(si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t port,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t slot_status,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t failed_tags,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t timedout_tags,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t aborting_tags,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t reset_tags)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t finished_tags, unfinished_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int tmpslot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt_t *satapkt;
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek struct sata_cmd_flags *flagsp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_mop_commands entered: slot_status: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_mop_commands: failed_tags: 0x%x, timedout_tags: 0x%x"
193974072f41a843678abf5f61979c748687e66bSherry Moore "aborting_tags: 0x%x, reset_tags: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore failed_tags,
193974072f41a843678abf5f61979c748687e66bSherry Moore timedout_tags,
193974072f41a843678abf5f61979c748687e66bSherry Moore aborting_tags,
193974072f41a843678abf5f61979c748687e66bSherry Moore reset_tags);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We could be here for four reasons: abort, reset,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * timeout or error handling. Only one such mopping
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is allowed at a time.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf finished_tags = si_portp->siport_pending_tags &
193974072f41a843678abf5f61979c748687e66bSherry Moore ~slot_status & SI_SLOT_MASK;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf unfinished_tags = slot_status & SI_SLOT_MASK &
193974072f41a843678abf5f61979c748687e66bSherry Moore ~failed_tags &
193974072f41a843678abf5f61979c748687e66bSherry Moore ~aborting_tags &
193974072f41a843678abf5f61979c748687e66bSherry Moore ~reset_tags &
193974072f41a843678abf5f61979c748687e66bSherry Moore ~timedout_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Send up the finished_tags with SATA_PKT_COMPLETED. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf while (finished_tags) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf tmpslot = ddi_ffs(finished_tags) - 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (tmpslot == -1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt = si_portp->siport_slot_pkts[tmpslot];
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan if (satapkt != NULL &&
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek port, tmpslot);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
c03acfcad7780db4ddf763511a82026680b3b2c1ls
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_mop_commands sending up completed satapkt: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore satapkt);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(finished_tags, tmpslot);
a3f55fb1977ba058abdedc838f93a52aeff2d667xun ni - Sun Microsystems - Beijing China SENDUP_PACKET(si_portp, satapkt, SATA_PKT_COMPLETED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(finished_tags == 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Send up failed_tags with SATA_PKT_DEV_ERROR. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf while (failed_tags) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf tmpslot = ddi_ffs(failed_tags) - 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (tmpslot == -1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp, "si3124: si_mop_commands: "
193974072f41a843678abf5f61979c748687e66bSherry Moore "handling failed slot: 0x%x", tmpslot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt = si_portp->siport_slot_pkts[tmpslot];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan if (satapkt != NULL) {
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan if (satapkt->satapkt_device.satadev_type ==
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan SATA_DTYPE_ATAPICD) {
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan si_set_sense_data(satapkt, SATA_PKT_DEV_ERROR);
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
c03acfcad7780db4ddf763511a82026680b3b2c1ls
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp = &satapkt->satapkt_cmd.satacmd_flags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp->sata_copy_out_lba_low_msb = B_TRUE;
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp->sata_copy_out_lba_mid_msb = B_TRUE;
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp->sata_copy_out_lba_high_msb = B_TRUE;
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp->sata_copy_out_lba_low_lsb = B_TRUE;
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp->sata_copy_out_lba_mid_lsb = B_TRUE;
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp->sata_copy_out_lba_high_lsb = B_TRUE;
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp->sata_copy_out_error_reg = B_TRUE;
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp->sata_copy_out_sec_count_msb = B_TRUE;
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp->sata_copy_out_sec_count_lsb = B_TRUE;
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan flagsp->sata_copy_out_device_reg = B_TRUE;
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp,
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan port, tmpslot);
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan /*
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan * In the case of NCQ command failures, the error is
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan * overwritten by the one obtained from issuing of a
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan * READ LOG EXTENDED command.
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan */
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan if (si_portp->siport_err_tags_SDBERROR &
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan (1 << tmpslot)) {
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan satapkt->satapkt_cmd.satacmd_error_reg =
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan si_read_log_ext(si_ctlp, si_portp, port);
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(failed_tags, tmpslot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
a3f55fb1977ba058abdedc838f93a52aeff2d667xun ni - Sun Microsystems - Beijing China SENDUP_PACKET(si_portp, satapkt, SATA_PKT_DEV_ERROR);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(failed_tags == 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Send up timedout_tags with SATA_PKT_TIMEOUT. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf while (timedout_tags) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf tmpslot = ddi_ffs(timedout_tags) - 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (tmpslot == -1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt = si_portp->siport_slot_pkts[tmpslot];
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_mop_commands sending "
193974072f41a843678abf5f61979c748687e66bSherry Moore "spkt up with PKT_TIMEOUT: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore satapkt);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(timedout_tags, tmpslot);
a3f55fb1977ba058abdedc838f93a52aeff2d667xun ni - Sun Microsystems - Beijing China SENDUP_PACKET(si_portp, satapkt, SATA_PKT_TIMEOUT);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(timedout_tags == 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Send up aborting packets with SATA_PKT_ABORTED. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf while (aborting_tags) {
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan tmpslot = ddi_ffs(aborting_tags) - 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (tmpslot == -1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt = si_portp->siport_slot_pkts[tmpslot];
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_mop_commands aborting spkt: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore satapkt);
ed385ad99ff0b80b8baeaeabe87ccbe036a89339Mark Logan if (satapkt != NULL && satapkt->satapkt_device.satadev_type ==
193974072f41a843678abf5f61979c748687e66bSherry Moore SATA_DTYPE_ATAPICD) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_set_sense_data(satapkt, SATA_PKT_ABORTED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(aborting_tags, tmpslot);
a3f55fb1977ba058abdedc838f93a52aeff2d667xun ni - Sun Microsystems - Beijing China SENDUP_PACKET(si_portp, satapkt, SATA_PKT_ABORTED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(aborting_tags == 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Reset tags are sent up to framework with SATA_PKT_RESET. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf while (reset_tags) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf tmpslot = ddi_ffs(reset_tags) - 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (tmpslot == -1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt = si_portp->siport_slot_pkts[tmpslot];
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_mop_commands sending PKT_RESET for "
193974072f41a843678abf5f61979c748687e66bSherry Moore "reset spkt: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore satapkt);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(reset_tags, tmpslot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
a3f55fb1977ba058abdedc838f93a52aeff2d667xun ni - Sun Microsystems - Beijing China SENDUP_PACKET(si_portp, satapkt, SATA_PKT_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(reset_tags == 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan /* Send up the unfinished_tags with SATA_PKT_RESET. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf while (unfinished_tags) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf tmpslot = ddi_ffs(unfinished_tags) - 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (tmpslot == -1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt = si_portp->siport_slot_pkts[tmpslot];
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan "si_mop_commands sending SATA_PKT_RESET for "
193974072f41a843678abf5f61979c748687e66bSherry Moore "retry spkt: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore satapkt);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(unfinished_tags, tmpslot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan SENDUP_PACKET(si_portp, satapkt, SATA_PKT_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(unfinished_tags == 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan si_portp->mopping_in_progress--;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan ASSERT(si_portp->mopping_in_progress >= 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Called by the sata framework to abort the previously sent packet(s).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We reset the device and mop the commands on the port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_tran_abort(dev_info_t *dip, sata_pkt_t *spkt, int flag)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t slot_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int tmpslot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t aborting_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t finished_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port = spkt->satapkt_device.satadev_addr.cport;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp, "si_tran_abort on port: %x", port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan /*
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan * If already mopping, then no need to abort anything.
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan */
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan if (si_portp->mopping_in_progress > 0) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan "si_tran_abort: port %d mopping "
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan "in progress, so just return", port);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan mutex_exit(&si_portp->siport_mutex);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan return (SATA_SUCCESS);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan }
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore !si_portp->siport_active) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_intr_phy_ready_change() may have rendered it to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * PORT_TYPE_NODEV. cfgadm operation may have rendered
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * it inactive.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (flag == SATA_ABORT_ALL_PACKETS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf aborting_tags = si_portp->siport_pending_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Need to abort a single packet.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Search our siport_slot_pkts[] list for matching spkt.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf aborting_tags = 0xffffffff; /* 0xffffffff is impossible tag */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (tmpslot = 0; tmpslot < SI_NUM_SLOTS; tmpslot++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_slot_pkts[tmpslot] == spkt) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf aborting_tags = (0x1 << tmpslot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (aborting_tags == 0xffffffff) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* requested packet is not on pending list. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf fill_dev_sregisters(si_ctlp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore &spkt->satapkt_device);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan si_portp->mopping_in_progress++;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port, SI_DEVICE_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Compute which have finished and which need to be retried.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The finished tags are siport_pending_tags minus the slot_status.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The aborting_tags have to be reduced by finished_tags since we
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * can't possibly abort a tag which had finished already.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf finished_tags = si_portp->siport_pending_tags &
193974072f41a843678abf5f61979c748687e66bSherry Moore ~slot_status & SI_SLOT_MASK;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf aborting_tags &= ~finished_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_mop_commands(si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port,
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, /* failed_tags */
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, /* timedout_tags */
193974072f41a843678abf5f61979c748687e66bSherry Moore aborting_tags,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0); /* reset_tags */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Used to reject all the pending packets on a port during a reset
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * operation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_reject_all_reset_pkts(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t slot_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t reset_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_RESET, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_reject_all_reset_pkts on port: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Compute which tags need to be sent up. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf reset_tags = slot_status & SI_SLOT_MASK;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan si_portp->mopping_in_progress++;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_mop_commands(si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port,
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, /* failed_tags */
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, /* timedout_tags */
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, /* aborting_tags */
193974072f41a843678abf5f61979c748687e66bSherry Moore reset_tags);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Called by sata framework to reset a port(s) or device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_tran_reset_dport(dev_info_t *dip, sata_device_t *sd)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t port = sd->satadev_addr.cport;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int i;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int retval = SI_SUCCESS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_RESET, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_tran_reset_port entry: port: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (sd->satadev_addr.qual) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case SATA_ADDR_CPORT:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan /*
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan * If already mopping, then no need to reset or mop again.
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan */
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan if (si_portp->mopping_in_progress > 0) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_RESET, si_portp,
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan "si_tran_reset_dport: CPORT port %d mopping "
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan "in progress, so just return", port);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan mutex_exit(&si_portp->siport_mutex);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan retval = SI_SUCCESS;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan break;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan }
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf retval = si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore SI_PORT_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_reject_all_reset_pkts(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case SATA_ADDR_DCPORT:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore !si_portp->siport_active) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf retval = SI_FAILURE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan /*
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan * If already mopping, then no need to reset or mop again.
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan */
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan if (si_portp->mopping_in_progress > 0) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_RESET, si_portp,
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan "si_tran_reset_dport: DCPORT port %d mopping "
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan "in progress, so just return", port);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan mutex_exit(&si_portp->siport_mutex);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan retval = SI_SUCCESS;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan break;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan }
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf retval = si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore SI_DEVICE_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_reject_all_reset_pkts(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case SATA_ADDR_CNTRL:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (i = 0; i < si_ctlp->sictl_num_ports; i++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan si_portp = si_ctlp->sictl_ports[i];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan /*
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan * If mopping, then all the pending commands are being
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan * mopped, therefore there is nothing else to do.
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan */
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan if (si_portp->mopping_in_progress > 0) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_RESET, si_portp,
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan "si_tran_reset_dport: CNTRL port %d mopping"
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan " in progress, so just return", i);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan mutex_exit(&si_portp->siport_mutex);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan retval = SI_SUCCESS;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan break;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan }
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf retval = si_reset_dport_wait_till_ready(si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp, i, SI_PORT_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (retval) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan si_reject_all_reset_pkts(si_ctlp, si_portp, i);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case SATA_ADDR_PMPORT:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case SATA_ADDR_DPMPORT:
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_RESET, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "port mult reset not implemented yet", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* FALLSTHROUGH */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf default:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf retval = SI_FAILURE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (retval);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Called by sata framework to activate a port as part of hotplug.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note: Not port-mult aware.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_tran_hotplug_port_activate(dev_info_t *dip, sata_device_t *satadev)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port = satadev->satadev_addr.cport;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_EVENT, si_portp, "si_tran_hotplug_port_activate entry",
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_enable_port_interrupts(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Reset the device so that a si_find_dev_signature() would trigger.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * But this reset is an internal operation; the sata framework does
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * not need to know about it.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore SI_DEVICE_RESET|SI_RESET_NO_EVENTS_UP);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satadev->satadev_state = SATA_STATE_READY;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_active = PORT_ACTIVE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf fill_dev_sregisters(si_ctlp, port, satadev);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Called by sata framework to deactivate a port as part of hotplug.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note: Not port-mult aware.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_tran_hotplug_port_deactivate(dev_info_t *dip, sata_device_t *satadev)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port = satadev->satadev_addr.cport;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG(SIDBG_EVENT, "si_tran_hotplug_port_deactivate entry", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_pending_tags & SI_SLOT_MASK) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * There are pending commands on this port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Fail the deactivate request.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satadev->satadev_state = SATA_STATE_READY;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* mark the device as not accessible any more. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_active = PORT_INACTIVE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* disable the interrupts on the port. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_disable_port_interrupts(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satadev->satadev_state = SATA_PSTATE_SHUTDOWN;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf fill_dev_sregisters(si_ctlp, port, satadev);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Since we are implementing the port deactivation in software only,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * we need to fake a valid value for sstatus.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SSTATUS_SET_DET(satadev->satadev_scr.sstatus, SSTATUS_DET_PHYOFFLINE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SSTATUS_SET_IPM(satadev->satadev_scr.sstatus, SSTATUS_IPM_NODEV_NOPHY);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SATA_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Allocates the si_port_state_t.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_alloc_port_state(si_ctl_state_t *si_ctlp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_ports[port] = (si_port_state_t *)kmem_zalloc(
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (si_port_state_t), KM_SLEEP);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_init(&si_portp->siport_mutex, NULL, MUTEX_DRIVER,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)(uintptr_t)si_ctlp->sictl_intr_pri);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* allocate prb & sgt pkts for this port. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_alloc_prbpool(si_ctlp, port)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_alloc_sgbpool(si_ctlp, port)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_dealloc_prbpool(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan /* Allocate the argument for the timeout */
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_portp->siport_event_args =
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan kmem_zalloc(sizeof (si_event_arg_t), KM_SLEEP);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_active = PORT_ACTIVE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Deallocates the si_port_state_t.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_dealloc_port_state(si_ctl_state_t *si_ctlp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan kmem_free(si_portp->siport_event_args, sizeof (si_event_arg_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_dealloc_sgbpool(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_dealloc_prbpool(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_destroy(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Allocates the SGB (Scatter Gather Block) incore buffer.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_alloc_sgbpool(si_ctl_state_t *si_ctlp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint_t cookie_count;
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China size_t incore_sgbpool_size = SI_NUM_SLOTS * sizeof (si_sgblock_t)
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China * si_dma_sg_number;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf size_t ret_len;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_cookie_t sgbpool_dma_cookie;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* allocate sgbpool dma handle. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_dma_alloc_handle(si_ctlp->sictl_devinfop,
193974072f41a843678abf5f61979c748687e66bSherry Moore &prb_sgt_dma_attr,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DMA_SLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore &si_portp->siport_sgbpool_dma_handle) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* allocate the memory for sgbpool. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_dma_mem_alloc(si_portp->siport_sgbpool_dma_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore incore_sgbpool_size,
193974072f41a843678abf5f61979c748687e66bSherry Moore &accattr,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DMA_SLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&si_portp->siport_sgbpool,
193974072f41a843678abf5f61979c748687e66bSherry Moore &ret_len,
193974072f41a843678abf5f61979c748687e66bSherry Moore &si_portp->siport_sgbpool_acc_handle) != NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* error.. free the dma handle. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* now bind it */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_dma_addr_bind_handle(si_portp->siport_sgbpool_dma_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)si_portp->siport_sgbpool,
193974072f41a843678abf5f61979c748687e66bSherry Moore incore_sgbpool_size,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DMA_CONSISTENT,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DMA_SLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore &sgbpool_dma_cookie,
193974072f41a843678abf5f61979c748687e66bSherry Moore &cookie_count) != DDI_DMA_MAPPED) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* error.. free the dma handle & free the memory. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_mem_free(&si_portp->siport_sgbpool_acc_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_sgbpool_physaddr = sgbpool_dma_cookie.dmac_laddress;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Deallocates the SGB (Scatter Gather Block) incore buffer.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_dealloc_sgbpool(si_ctl_state_t *si_ctlp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Unbind the dma handle first. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_dma_unbind_handle(si_portp->siport_sgbpool_dma_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Then free the underlying memory. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_mem_free(&si_portp->siport_sgbpool_acc_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now free the handle itself. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Allocates the PRB (Port Request Block) incore packets.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_alloc_prbpool(si_ctl_state_t *si_ctlp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint_t cookie_count;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf size_t incore_pkt_size = SI_NUM_SLOTS * sizeof (si_prb_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf size_t ret_len;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_cookie_t prbpool_dma_cookie;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* allocate prb pkts. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_dma_alloc_handle(si_ctlp->sictl_devinfop,
193974072f41a843678abf5f61979c748687e66bSherry Moore &prb_sgt_dma_attr,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DMA_SLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore &si_portp->siport_prbpool_dma_handle) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_dma_mem_alloc(si_portp->siport_prbpool_dma_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore incore_pkt_size,
193974072f41a843678abf5f61979c748687e66bSherry Moore &accattr,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DMA_SLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&si_portp->siport_prbpool,
193974072f41a843678abf5f61979c748687e66bSherry Moore &ret_len,
193974072f41a843678abf5f61979c748687e66bSherry Moore &si_portp->siport_prbpool_acc_handle) != NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* error.. free the dma handle. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_dma_addr_bind_handle(si_portp->siport_prbpool_dma_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)si_portp->siport_prbpool,
193974072f41a843678abf5f61979c748687e66bSherry Moore incore_pkt_size,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DMA_CONSISTENT,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DMA_SLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore &prbpool_dma_cookie,
193974072f41a843678abf5f61979c748687e66bSherry Moore &cookie_count) != DDI_DMA_MAPPED) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* error.. free the dma handle & free the memory. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_mem_free(&si_portp->siport_prbpool_acc_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_prbpool_physaddr =
193974072f41a843678abf5f61979c748687e66bSherry Moore prbpool_dma_cookie.dmac_laddress;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Deallocates the PRB (Port Request Block) incore packets.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_dealloc_prbpool(si_ctl_state_t *si_ctlp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Unbind the prb dma handle first. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_dma_unbind_handle(si_portp->siport_prbpool_dma_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Then free the underlying memory. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_mem_free(&si_portp->siport_prbpool_acc_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now free the handle itself. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Soft-reset the port to find the signature of the device connected to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_find_dev_signature(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int pmp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_prb_t *prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t slot_status, signature;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int slot, loop_count;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_find_dev_signature enter: port: %x, pmp: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port, pmp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Build a Soft Reset PRB in host memory. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot = si_claim_free_slot(si_ctlp, si_portp, port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (slot == SI_FAILURE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Empty slot could not be found. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (pmp != PORTMULT_CONTROL_PORT) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are behind port multiplier. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_portmult_state.sipm_port_type[pmp] =
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_TYPE_NODEV;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_port_type = PORT_TYPE_NODEV;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf prb = &si_portp->siport_prbpool[slot];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bzero((void *)prb, sizeof (si_prb_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_PMP(prb->prb_fis, pmp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_PRB_CONTROL_SOFT_RESET(prb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#if SI_DEBUG
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_debug_flags & SIDBG_DUMP_PRB) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf char *ptr;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int j;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ptr = (char *)prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "si_find_dev_signature, prb: ");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (j = 0; j < (sizeof (si_prb_t)); j++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (j%4 == 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "----");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "%x ", ptr[j]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* SI_DEBUG */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* deliver soft reset prb to empty slot. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Loop till the soft reset is finished. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_SOFT_RESET) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are effectively timing out after 10 sec. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_find_dev_signature: loop count: %d, slot_status: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore loop_count, slot_status);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Read device signature from command slot. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf signature = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SIGNATURE_MSB(si_ctlp, port, slot)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf signature <<= 8;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf signature |= (0xff & ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SIGNATURE_LSB(si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port, slot))));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp, "Device signature: 0x%x", signature);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (signature == SI_SIGNATURE_PORT_MULTIPLIER) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Found multiplier at cport: 0x%d, pmport: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port, pmp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (pmp != PORTMULT_CONTROL_PORT) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * It is wrong to chain a port multiplier behind
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * another port multiplier.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_portmult_state.sipm_port_type[pmp] =
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_TYPE_NODEV;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_port_type = PORT_TYPE_MULTIPLIER;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_enumerate_port_multiplier(si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_init_port(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else if (signature == SI_SIGNATURE_ATAPI) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (pmp != PORTMULT_CONTROL_PORT) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are behind port multiplier. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_portmult_state.sipm_port_type[pmp] =
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_TYPE_ATAPI;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_port_type = PORT_TYPE_ATAPI;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_init_port(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Found atapi at : cport: %x, pmport: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port, pmp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else if (signature == SI_SIGNATURE_DISK) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (pmp != PORTMULT_CONTROL_PORT) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are behind port multiplier. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_portmult_state.sipm_port_type[pmp] =
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_TYPE_DISK;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_port_type = PORT_TYPE_DISK;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_init_port(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "found disk at : cport: %x, pmport: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port, pmp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (pmp != PORTMULT_CONTROL_PORT) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are behind port multiplier. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_portmult_state.sipm_port_type[pmp] =
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_TYPE_UNKNOWN;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_port_type = PORT_TYPE_UNKNOWN;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Found unknown signature 0x%x at: port: %x, pmp: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore signature, port, pmp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Polls for the completion of the command. This is safe with both
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * interrupts enabled or disabled.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_poll_cmd(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int slot,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt_t *satapkt)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t slot_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int pkt_timeout_ticks;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t port_intr_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int in_panic = ddi_in_panic();
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ENTRY, si_portp, "si_poll_cmd entered: port: 0x%x", port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf pkt_timeout_ticks = drv_usectohz((clock_t)satapkt->satapkt_time *
193974072f41a843678abf5f61979c748687e66bSherry Moore 1000000);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* we start out with SATA_PKT_COMPLETED as the satapkt_reason */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt->satapkt_reason = SATA_PKT_COMPLETED;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (in_panic) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If we are in panic, we can't rely on
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * timers; so, busy wait instead of delay().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf drv_usecwait(SI_1MS_USECS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_1MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf pkt_timeout_ticks -= SI_1MS_TICKS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (pkt_timeout_ticks > 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (satapkt->satapkt_reason != SATA_PKT_COMPLETED) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* The si_mop_command() got to our packet before us */
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek return;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupts and timers may not be working properly in a crash dump
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * situation; we may need to handle all the three conditions here:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * successful completion, packet failure and packet timeout.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (IS_ATTENTION_RAISED(slot_status)) { /* error seen on port */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_poll_cmd: port_intr_status: 0x%x, port: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port_intr_status, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_COMMAND_ERROR) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_command_error(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek return;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Why do we need to call si_intr_command_error() ?
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Answer: Even if the current packet is not the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * offending command, we need to restart the stalled
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * port; (may be, the interrupts are not working well
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * in panic condition). The call to routine
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_intr_command_error() will achieve that.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * What if the interrupts are working fine and the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_intr_command_error() gets called once more from
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * interrupt context ?
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Answer: The second instance of routine
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_intr_command_error() will not mop anything
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * since the first error handler has already blown
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * away the hardware pending queues through reset.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Will the si_intr_command_error() hurt current
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * packet ?
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Answer: No.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Ignore any non-error interrupts at this stage */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port)),
193974072f41a843678abf5f61979c748687e66bSherry Moore port_intr_status & INTR_MASK);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt->satapkt_reason = SATA_PKT_TIMEOUT;
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } /* else: the command completed successfully */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp, port, slot);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((satapkt->satapkt_cmd.satacmd_cmd_reg ==
193974072f41a843678abf5f61979c748687e66bSherry Moore SATAC_WRITE_FPDMA_QUEUED) ||
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (satapkt->satapkt_cmd.satacmd_cmd_reg ==
193974072f41a843678abf5f61979c748687e66bSherry Moore SATAC_READ_FPDMA_QUEUED)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_pending_ncq_count--;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * tidbit: What is the interaction of abort with polling ?
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * What happens if the current polled pkt is aborted in parallel ?
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Answer: Assuming that the si_mop_commands() completes ahead
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * of polling, all it does is to set the satapkt_reason to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SPKT_PKT_ABORTED. That would be fine with us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The same logic applies to reset interacting with polling.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Searches for and claims a free slot.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns: SI_FAILURE if no slots found
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * claimed slot number if successful
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_claim_free_slot(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t free_slots;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ENTRY, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_claim_free_slot entry: siport_pending_tags: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp->siport_pending_tags);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf free_slots = (~si_portp->siport_pending_tags) & SI_SLOT_MASK;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot = ddi_ffs(free_slots) - 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (slot == -1) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_claim_free_slot: no empty slots", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_pending_tags |= (0x1 << slot);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp, "si_claim_free_slot: found slot: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Builds the PRB for the sata packet and delivers it to controller.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * slot number if we can obtain a slot successfully
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * otherwise, return SI_FAILURE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_deliver_satapkt(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt_t *spkt)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_prb_t *prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_cmd_t *cmd;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_sge_t *sgep; /* scatter gather entry pointer */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_sgt_t *sgtp; /* scatter gather table pointer */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_sgblock_t *sgbp; /* scatter gather block pointer */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int i, j, cookie_index;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int ncookies;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int is_atapi = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_dma_cookie_t cookie;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot = si_claim_free_slot(si_ctlp, si_portp, port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (slot == SI_FAILURE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (spkt->satapkt_device.satadev_type == SATA_DTYPE_ATAPICD) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf is_atapi = 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore !si_portp->siport_active) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_intr_phy_ready_change() may have rendered it to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * PORT_TYPE_NODEV. cfgadm operation may have rendered
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * it inactive.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan CLEAR_BIT(si_portp->siport_pending_tags, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf prb = &(si_portp->siport_prbpool[slot]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bzero((void *)prb, sizeof (si_prb_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmd = &spkt->satapkt_cmd;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ENTRY, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_deliver_satpkt entry: cmd_reg: 0x%x, slot: 0x%x, \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port: %x, satapkt: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore cmd->satacmd_cmd_reg, slot, port, (uint32_t)(intptr_t)spkt);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now fill the prb. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (is_atapi) {
c03acfcad7780db4ddf763511a82026680b3b2c1ls if (spkt->satapkt_cmd.satacmd_flags.sata_data_direction ==
c03acfcad7780db4ddf763511a82026680b3b2c1ls SATA_DIR_READ) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_PRB_CONTROL_PKT_READ(prb);
c03acfcad7780db4ddf763511a82026680b3b2c1ls } else if (spkt->satapkt_cmd.satacmd_flags.sata_data_direction
c03acfcad7780db4ddf763511a82026680b3b2c1ls == SATA_DIR_WRITE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_PRB_CONTROL_PKT_WRITE(prb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((spkt->satapkt_device.satadev_addr.qual == SATA_ADDR_PMPORT) ||
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (spkt->satapkt_device.satadev_addr.qual == SATA_ADDR_DPMPORT)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_PMP(prb->prb_fis,
193974072f41a843678abf5f61979c748687e66bSherry Moore spkt->satapkt_device.satadev_addr.pmport);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_COMMAND(prb->prb_fis, cmd->satacmd_cmd_reg);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_FEATURES(prb->prb_fis, cmd->satacmd_features_reg);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_SECTOR_COUNT(prb->prb_fis, cmd->satacmd_sec_count_lsb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (cmd->satacmd_addr_type) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama case 0:
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama /*
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * satacmd_addr_type will be 0 for the commands below:
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_PACKET
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_IDLE_IM
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_STANDBY_IM
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_DOWNLOAD_MICROCODE
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_FLUSH_CACHE
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_SET_FEATURES
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_SMART
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_ID_PACKET_DEVICE
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_ID_DEVICE
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_READ_PORTMULT
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama * SATAC_WRITE_PORTMULT
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama */
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama /* FALLTHRU */
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case ATA_ADDR_LBA:
1aae9af034dd41d01de0abaaeadbf955d9951057Praveen Kumar Dasaraju Rama /* FALLTHRU */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case ATA_ADDR_LBA28:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA[7:0] */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_SECTOR(prb->prb_fis, cmd->satacmd_lba_low_lsb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA[15:8] */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CYL_LOW(prb->prb_fis, cmd->satacmd_lba_mid_lsb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA[23:16] */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CYL_HI(prb->prb_fis, cmd->satacmd_lba_high_lsb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA [27:24] (also called dev_head) */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_DEV_HEAD(prb->prb_fis, cmd->satacmd_device_reg);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case ATA_ADDR_LBA48:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA[7:0] */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_SECTOR(prb->prb_fis, cmd->satacmd_lba_low_lsb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA[15:8] */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CYL_LOW(prb->prb_fis, cmd->satacmd_lba_mid_lsb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA[23:16] */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CYL_HI(prb->prb_fis, cmd->satacmd_lba_high_lsb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA [31:24] */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_SECTOR_EXP(prb->prb_fis, cmd->satacmd_lba_low_msb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA [39:32] */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CYL_LOW_EXP(prb->prb_fis, cmd->satacmd_lba_mid_msb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA [47:40] */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CYL_HI_EXP(prb->prb_fis, cmd->satacmd_lba_high_msb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Set dev_head */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_DEV_HEAD(prb->prb_fis, cmd->satacmd_device_reg);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Set the extended sector count and features */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_SECTOR_COUNT_EXP(prb->prb_fis,
193974072f41a843678abf5f61979c748687e66bSherry Moore cmd->satacmd_sec_count_msb);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_FEATURES_EXP(prb->prb_fis,
193974072f41a843678abf5f61979c748687e66bSherry Moore cmd->satacmd_features_reg_ext);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
c03acfcad7780db4ddf763511a82026680b3b2c1ls if (cmd->satacmd_flags.sata_queued) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * For queued commands, the TAG for the sector count lsb is
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * generated from current slot number.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_SECTOR_COUNT(prb->prb_fis, slot << 3);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((cmd->satacmd_cmd_reg == SATAC_WRITE_FPDMA_QUEUED) ||
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (cmd->satacmd_cmd_reg == SATAC_READ_FPDMA_QUEUED)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_pending_ncq_count++;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* *** now fill the scatter gather list ******* */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (is_atapi) { /* It is an ATAPI drive */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* atapi command goes into sge0 */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bcopy(cmd->satacmd_acdb, &prb->prb_sge0, sizeof (si_sge_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now fill sge1 with pointer to external SGT. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (spkt->satapkt_cmd.satacmd_num_dma_cookies) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf prb->prb_sge1.sge_addr =
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp->siport_sgbpool_physaddr +
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China slot * sizeof (si_sgblock_t) * si_dma_sg_number;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_SGE_LNK(prb->prb_sge1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_SGE_TRM(prb->prb_sge1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Fill the sge0 */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (spkt->satapkt_cmd.satacmd_num_dma_cookies) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf prb->prb_sge0.sge_addr =
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp->siport_sgbpool_physaddr +
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China slot * sizeof (si_sgblock_t) * si_dma_sg_number;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_SGE_LNK(prb->prb_sge0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_SGE_TRM(prb->prb_sge0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* sge1 is left empty in non-ATAPI case */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China bzero(&si_portp->siport_sgbpool[slot * si_dma_sg_number],
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China sizeof (si_sgblock_t) * si_dma_sg_number);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ncookies = spkt->satapkt_cmd.satacmd_num_dma_cookies;
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China ASSERT(ncookies <= (SGE_LENGTH(si_dma_sg_number)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_COOKIES, si_portp, "total ncookies: %d", ncookies);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ncookies == 0) {
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sgtp = &sgbp->sgb_sgt[0];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sgep = &sgtp->sgt_sge[0];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* No cookies. Terminate the chain. */
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_COOKIES, si_portp, "empty cookies: terminating.",
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sgep->sge_addr_low = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sgep->sge_addr_high = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sgep->sge_data_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_SGE_TRM((*sgep));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf goto sgl_fill_done;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China for (i = 0, cookie_index = 0,
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number];
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China i < si_dma_sg_number; i++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China sgtp = &sgbp->sgb_sgt[0] + i;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now fill the first 3 entries of SGT in the loop below. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (j = 0, sgep = &sgtp->sgt_sge[0];
193974072f41a843678abf5f61979c748687e66bSherry Moore ((j < 3) && (cookie_index < ncookies-1));
193974072f41a843678abf5f61979c748687e66bSherry Moore j++, cookie_index++, sgep++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(cookie_index < ncookies);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_COOKIES, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "inner loop: cookie_index: %d, ncookies: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore cookie_index,
193974072f41a843678abf5f61979c748687e66bSherry Moore ncookies);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cookie = spkt->satapkt_cmd.
193974072f41a843678abf5f61979c748687e66bSherry Moore satacmd_dma_cookie_list[cookie_index];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sgep->sge_addr_low = cookie._dmu._dmac_la[0];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sgep->sge_addr_high = cookie._dmu._dmac_la[1];
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China sgep->sge_data_count = (uint32_t)cookie.dmac_size;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If this happens to be the last cookie, we terminate it here.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Otherwise, we link to next SGT.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (cookie_index == ncookies-1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* This is the last cookie. Terminate the chain. */
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_COOKIES, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "filling the last: cookie_index: %d, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "ncookies: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore cookie_index,
193974072f41a843678abf5f61979c748687e66bSherry Moore ncookies);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cookie = spkt->satapkt_cmd.
193974072f41a843678abf5f61979c748687e66bSherry Moore satacmd_dma_cookie_list[cookie_index];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sgep->sge_addr_low = cookie._dmu._dmac_la[0];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sgep->sge_addr_high = cookie._dmu._dmac_la[1];
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China sgep->sge_data_count = (uint32_t)cookie.dmac_size;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_SGE_TRM((*sgep));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break; /* we break the loop */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* This is not the last one. So link it. */
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_COOKIES, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "linking SGT: cookie_index: %d, ncookies: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore cookie_index,
193974072f41a843678abf5f61979c748687e66bSherry Moore ncookies);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sgep->sge_addr = si_portp->siport_sgbpool_physaddr +
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China slot * sizeof (si_sgblock_t) * si_dma_sg_number +
193974072f41a843678abf5f61979c748687e66bSherry Moore (i+1) * sizeof (si_sgt_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_SGE_LNK((*sgep));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* *** finished filling the scatter gather list ******* */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsgl_fill_done:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now remember the sata packet in siport_slot_pkts[]. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_slot_pkts[slot] = spkt;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are overloading satapkt_hba_driver_private with
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * watched_cycle count.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spkt->satapkt_hba_driver_private = (void *)(intptr_t)0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (is_atapi) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* program the packet_lenth if it is atapi device. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifdef ATAPI_2nd_PHASE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Framework needs to calculate the acdb_len based on
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * identify packet data. This needs to be accomplished
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * in second phase of the project.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT((cmd->satacmd_acdb_len == 12) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (cmd->satacmd_acdb_len == 16));
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp, "deliver: acdb_len: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore cmd->satacmd_acdb_len);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (cmd->satacmd_acdb_len == 16) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_SET_BITS_PACKET_LEN);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_CLEAR_BITS_PACKET_LEN);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#else /* ATAPI_2nd_PHASE */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* hard coding for now to 12 bytes */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_CLEAR_BITS_PACKET_LEN);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* ATAPI_2nd_PHASE */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#if SI_DEBUG
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_debug_flags & SIDBG_DUMP_PRB) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(is_atapi && (prb->prb_sge0.sge_addr_low == 0))) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Do not dump the atapi Test-Unit-Ready commands.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The sd_media_watch spews too many of these.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int *ptr;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_sge_t *tmpsgep;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int j;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China ptr = (int *)(void *)prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "si_deliver_satpkt prb: ");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "%x ", ptr[j]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_deliver_satpkt sgt: low, high, count link");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (j = 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore tmpsgep = (si_sge_t *)
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China &si_portp->siport_sgbpool[slot * si_dma_sg_number];
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China j < (sizeof (si_sgblock_t)/ sizeof (si_sge_t))
81a0678e1c5837dd278edbcc4a617a6c976e7673xun ni - Sun Microsystems - Beijing China *si_dma_sg_number;
193974072f41a843678abf5f61979c748687e66bSherry Moore j++, tmpsgep++) {
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China ptr = (int *)(void *)tmpsgep;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "%x %x %x %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore ptr[0],
193974072f41a843678abf5f61979c748687e66bSherry Moore ptr[1],
193974072f41a843678abf5f61979c748687e66bSherry Moore ptr[2],
193974072f41a843678abf5f61979c748687e66bSherry Moore ptr[3]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (IS_SGE_TRM_SET((*tmpsgep))) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* SI_DEBUG */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Deliver PRB */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Initialize the controller and set up driver data structures.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This routine can be called from three separate cases: DDI_ATTACH, PM_LEVEL_D0
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * and DDI_RESUME. The DDI_ATTACH case is different from other two cases; the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * memory allocation & device signature probing are attempted only during
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DDI_ATTACH case. In the case of PM_LEVEL_D0 & DDI_RESUME, we are starting
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * from a previously initialized state; so there is no need to allocate memory
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * or to attempt probing the device signatures.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_initialize_controller(si_ctl_state_t *si_ctlp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t port_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t SStatus;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t SControl;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama uint8_t port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si3124: si_initialize_controller entered", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Remove the Global Reset. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_global_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
193974072f41a843678abf5f61979c748687e66bSherry Moore GLOBAL_CONTROL_REG_BITS_CLEAR);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_ctlp->sictl_flags & SI_ATTACH) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We allocate the port state only during attach
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sequence. We don't want to do it during
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * suspend/resume sequence.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_alloc_port_state(si_ctlp, port)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama si_portp->siport_ctlp = si_ctlp;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama si_portp->siport_port_num = port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Clear Port Reset. */
0b0c3d307b4a6e7a73801251e4a6ab296acfc385johansen ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_SET_BITS_PORT_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_CLEAR_BITS_PORT_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Arm the interrupts for: Cmd completion, Cmd error,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Port Ready, PM Change, PhyRdyChange, Commwake,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * UnrecFIS, Devxchanged, SDBNotify.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore (INTR_COMMAND_COMPLETE |
193974072f41a843678abf5f61979c748687e66bSherry Moore INTR_COMMAND_ERROR |
193974072f41a843678abf5f61979c748687e66bSherry Moore INTR_PORT_READY |
193974072f41a843678abf5f61979c748687e66bSherry Moore INTR_POWER_CHANGE |
193974072f41a843678abf5f61979c748687e66bSherry Moore INTR_PHYRDY_CHANGE |
193974072f41a843678abf5f61979c748687e66bSherry Moore INTR_COMWAKE_RECEIVED |
193974072f41a843678abf5f61979c748687e66bSherry Moore INTR_UNRECOG_FIS |
193974072f41a843678abf5f61979c748687e66bSherry Moore INTR_DEV_XCHANGED |
193974072f41a843678abf5f61979c748687e66bSherry Moore INTR_SETDEVBITS_NOTIFY));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now enable the interrupts. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_enable_port_interrupts(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The following PHY initialization is redundant in
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * in x86 since the BIOS anyway does this as part of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * device enumeration during the power up. But this
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is a required step in sparc since there is no BIOS.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The way to initialize the PHY is to write a 1 and then
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a 0 to DET field of SControl register.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Fetch the current SControl before writing the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DET part with 1
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_SCONTROL(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
193974072f41a843678abf5f61979c748687e66bSherry Moore SControl);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Now fetch the SControl again and rewrite the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DET part with 0
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_SCONTROL(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
193974072f41a843678abf5f61979c748687e66bSherry Moore SControl);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * PHY may be initialized by now. Check the DET field of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SStatus to determine if there is a device present.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The DET field is valid only if IPM field indicates that
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the interface is in active state.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_SSTATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (SSTATUS_GET_IPM(SStatus) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_IPM_INTERFACE_ACTIVE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If the interface is not active, the DET field
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is considered not accurate. So we want to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * continue looping.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SSTATUS_SET_DET(SStatus,
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_DET_NODEV_NOPHY);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_SSTATUS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are effectively timing out after 0.1 sec.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (SSTATUS_GET_DET(SStatus) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_DET_DEVPRESENT_PHYONLINE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_initialize_controller: 1st loop count: %d, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "SStatus: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore loop_count,
193974072f41a843678abf5f61979c748687e66bSherry Moore SStatus);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((SSTATUS_GET_IPM(SStatus) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_IPM_INTERFACE_ACTIVE) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (SSTATUS_GET_DET(SStatus) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Either the port is not active or there
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is no device present.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_ports[port]->siport_port_type =
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_TYPE_NODEV;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf continue;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait until Port Ready */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_PORTREADY) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are effectively timing out after 0.5 sec.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (!(port_status & PORT_STATUS_BITS_PORT_READY));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_initialize_controller: 2nd loop count: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore loop_count);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_ctlp->sictl_flags & SI_ATTACH) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We want to probe for dev signature only during attach
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * case. Don't do it during suspend/resume sequence.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_status & PORT_STATUS_BITS_PORT_READY) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_find_dev_signature(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore PORTMULT_CONTROL_PORT);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_ports[port]->siport_port_type =
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_TYPE_NODEV;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_check_port_handles(si_portp) != DDI_SUCCESS) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_service_impact(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SERVICE_LOST);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan mutex_exit(&si_portp->siport_mutex);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan mutex_exit(&si_ctlp->sictl_mutex);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (SI_FAILURE);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Reverse of si_initialize_controller().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the sictl_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Falteseksi_deinitialize_controller(si_ctl_state_t *si_ctlp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_ctlp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si3124: si_deinitialize_controller entered", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* disable all the interrupts. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_disable_all_interrupts(si_ctlp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_ctlp->sictl_flags & SI_DETACH) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We want to dealloc all the memory in detach case.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_dealloc_port_state(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Prepare the port ready for usage.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_init_port(si_ctl_state_t *si_ctlp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_init_port entered: port: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Initialize the port. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_SET_BITS_PORT_INITIALIZE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek * Clear the InterruptNCOR (Interrupt No Clear on Read).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This step ensures that a mere reading of slot_status will clear
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the interrupt; no explicit clearing of interrupt condition
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * will be needed for successful completion of commands.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_CLEAR_BITS_INTR_NCoR);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* clear any pending interrupts at this point */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp, port)),
193974072f41a843678abf5f61979c748687e66bSherry Moore INTR_MASK);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Enumerate the devices connected to the port multiplier.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Once a device is detected, we call si_find_dev_signature()
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to find the type of device connected. Even though we are
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * called from within si_find_dev_signature(), there is no
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * recursion possible.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_enumerate_port_multiplier(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t num_dev_ports = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int pmport;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t SControl = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t SStatus = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t SError = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_enumerate_port_multiplier entered: port: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Enable Port Multiplier context switching. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_SET_BITS_PM_ENABLE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Read the num dev ports connected.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * GSCR[2] contains the number of device ports.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_read_portmult_reg(si_ctlp, si_portp, port, PORTMULT_CONTROL_PORT,
193974072f41a843678abf5f61979c748687e66bSherry Moore PSCR_REG2, &num_dev_ports)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_portmult_state.sipm_num_ports = num_dev_ports;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_enumerate_port_multiplier: ports found: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore num_dev_ports);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (pmport = 0; pmport < num_dev_ports-1; pmport++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Enable PHY by writing a 1, then a 0 to SControl
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * (i.e. PSCR[2]) DET field.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_read_portmult_reg(si_ctlp, si_portp, port, pmport,
193974072f41a843678abf5f61979c748687e66bSherry Moore PSCR_REG2, &SControl)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf continue;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* First write a 1 to DET field of SControl. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_write_portmult_reg(si_ctlp, si_portp, port, pmport,
193974072f41a843678abf5f61979c748687e66bSherry Moore PSCR_REG2, SControl)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf continue;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Then write a 0 to the DET field of SControl. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_write_portmult_reg(si_ctlp, si_portp, port, pmport,
193974072f41a843678abf5f61979c748687e66bSherry Moore PSCR_REG2, SControl)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf continue;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for PHYRDY by polling SStatus (i.e. PSCR[0]). */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_read_portmult_reg(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore pmport, PSCR_REG0, &SStatus)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "looping for PHYRDY: SStatus: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore SStatus);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (SSTATUS_GET_IPM(SStatus) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_IPM_INTERFACE_ACTIVE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If the interface is not active, the DET field
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is considered not accurate. So we want to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * continue looping.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SSTATUS_SET_DET(SStatus,
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_DET_NODEV_NOPHY);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_SSTATUS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are effectively timing out after 0.1 sec.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (SSTATUS_GET_DET(SStatus) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_DET_DEVPRESENT_PHYONLINE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_enumerate_port_multiplier: "
193974072f41a843678abf5f61979c748687e66bSherry Moore "loop count: %d, SStatus: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore loop_count,
193974072f41a843678abf5f61979c748687e66bSherry Moore SStatus);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((SSTATUS_GET_IPM(SStatus) ==
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_IPM_INTERFACE_ACTIVE) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (SSTATUS_GET_DET(SStatus) ==
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* The interface is active and the device is present */
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Status: %x, device exists",
193974072f41a843678abf5f61979c748687e66bSherry Moore SStatus);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Clear error bits in SError register (i.e. PSCR[1]
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * by writing back error bits.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_read_portmult_reg(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore pmport, PSCR_REG1, &SError)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf continue;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "SError bits are: %x", SError);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_write_portmult_reg(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore pmport, PSCR_REG1, SError)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf continue;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* There exists a device. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_find_dev_signature(si_ctlp, si_portp, port, pmport);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Read a port multiplier register.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_read_portmult_reg(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int pmport,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int regnum,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t *regval)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_prb_t *prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t *prb_word_ptr;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int i;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t slot_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ENTRY, si_portp, "si_read_portmult_reg: port: %x,"
193974072f41a843678abf5f61979c748687e66bSherry Moore "pmport: %x, regnum: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port, pmport, regnum);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot = si_claim_free_slot(si_ctlp, si_portp, port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (slot == SI_FAILURE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf prb = &(si_portp->siport_prbpool[slot]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bzero((void *)prb, sizeof (si_prb_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now fill the prb. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_COMMAND(prb->prb_fis, SATAC_READ_PM_REG);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_DEV_HEAD(prb->prb_fis, pmport);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_FEATURES(prb->prb_fis, regnum);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* no real data transfer is involved. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_SGE_TRM(prb->prb_sge0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#if SI_DEBUG
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_debug_flags & SIDBG_DUMP_PRB) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int *ptr;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int j;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China ptr = (int *)(void *)prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "%x ", ptr[j]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* SI_DEBUG */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Deliver PRB */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Loop till the command is finished. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "looping read_pm slot_status: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are effectively timing out after 0.5 sec. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "read_portmult_reg: loop count: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore loop_count);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now inspect the port LRAM for the modified FIS. */
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China prb_word_ptr = (uint32_t *)(void *)prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_check_port_handles(si_portp) != DDI_SUCCESS) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_service_impact(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SERVICE_UNAFFECTED);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (SI_FAILURE);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (((GET_FIS_COMMAND(prb->prb_fis) & 0x1) != 0) ||
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (GET_FIS_FEATURES(prb->prb_fis) != 0)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* command failed. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* command succeeded. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *regval = (GET_FIS_SECTOR_COUNT(prb->prb_fis) & 0xff) |
193974072f41a843678abf5f61979c748687e66bSherry Moore ((GET_FIS_SECTOR(prb->prb_fis) << 8) & 0xff00) |
193974072f41a843678abf5f61979c748687e66bSherry Moore ((GET_FIS_CYL_LOW(prb->prb_fis) << 16) & 0xff0000) |
193974072f41a843678abf5f61979c748687e66bSherry Moore ((GET_FIS_CYL_HI(prb->prb_fis) << 24) & 0xff000000);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Write a port multiplier register.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_write_portmult_reg(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int pmport,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int regnum,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t regval)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_prb_t *prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t *prb_word_ptr;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t slot_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int i;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ENTRY, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_write_portmult_reg: port: %x, pmport: %x,"
193974072f41a843678abf5f61979c748687e66bSherry Moore "regnum: %x, regval: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port, pmport, regnum, regval);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot = si_claim_free_slot(si_ctlp, si_portp, port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (slot == SI_FAILURE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf prb = &(si_portp->siport_prbpool[slot]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bzero((void *)prb, sizeof (si_prb_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now fill the prb. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_COMMAND(prb->prb_fis, SATAC_WRITE_PM_REG);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_DEV_HEAD(prb->prb_fis, pmport);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_FEATURES(prb->prb_fis, regnum);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_SECTOR_COUNT(prb->prb_fis, regval & 0xff);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_SECTOR(prb->prb_fis, (regval >> 8) & 0xff);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CYL_LOW(prb->prb_fis, (regval >> 16) & 0xff);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CYL_HI(prb->prb_fis, (regval >> 24) & 0xff);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* no real data transfer is involved. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_SGE_TRM(prb->prb_sge0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#if SI_DEBUG
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_debug_flags & SIDBG_DUMP_PRB) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int *ptr;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int j;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China ptr = (int *)(void *)prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "%x ", ptr[j]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* SI_DEBUG */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Deliver PRB */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Loop till the command is finished. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "looping write_pmp slot_status: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are effectively timing out after 0.5 sec. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "write_portmult_reg: loop count: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore loop_count);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now inspect the port LRAM for the modified FIS. */
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China prb_word_ptr = (uint32_t *)(void *)prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_check_port_handles(si_portp) != DDI_SUCCESS) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_service_impact(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SERVICE_UNAFFECTED);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (SI_FAILURE);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (((GET_FIS_COMMAND(prb->prb_fis) & 0x1) != 0) ||
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (GET_FIS_FEATURES(prb->prb_fis) != 0)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* command failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* command succeeded */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Set the auto sense data for ATAPI devices.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note: Currently the sense data is simulated; this code will be enhanced
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * in second phase to fetch the real sense data from the atapi device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_set_sense_data(sata_pkt_t *satapkt, int reason)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct scsi_extended_sense *sense;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense = (struct scsi_extended_sense *)
193974072f41a843678abf5f61979c748687e66bSherry Moore satapkt->satapkt_cmd.satacmd_rqsense;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bzero(sense, sizeof (struct scsi_extended_sense));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_valid = 1; /* Valid sense */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_class = 7; /* Response code 0x70 - current err */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_key = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_info_1 = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_info_2 = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_info_3 = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_info_4 = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_add_len = 6; /* Additional length */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_cmd_info[0] = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_cmd_info[1] = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_cmd_info[2] = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_cmd_info[3] = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_add_code = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_qual_code = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((reason == SATA_PKT_DEV_ERROR) || (reason == SATA_PKT_TIMEOUT)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense->es_key = KEY_HARDWARE_ERROR;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt service handler. We loop through each of the ports to find
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * if the interrupt belongs to any of them.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Bulk of the interrupt handling is actually done out of subroutines
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * like si_intr_command_complete() etc.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic uint_t
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr(caddr_t arg1, caddr_t arg2)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China si_ctl_state_t *si_ctlp = (si_ctl_state_t *)(void *)arg1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t global_intr_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t mask, port_intr_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf global_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)GLOBAL_INTERRUPT_STATUS(si_ctlp));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INTR, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_intr: global_int_status: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore global_intr_status);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (si_check_acc_handle(si_ctlp->sictl_global_acc_handle) !=
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SUCCESS) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_service_impact(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SERVICE_UNAFFECTED);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (DDI_INTR_UNCLAIMED);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(global_intr_status & SI31xx_INTR_PORT_MASK)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Sorry, the interrupt is not ours. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_INTR_UNCLAIMED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Loop for all the ports. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mask = 0x1 << port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(global_intr_status & mask)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf continue;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "s_intr: port_intr_status: 0x%x, port: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port_intr_status,
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_COMMAND_COMPLETE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_command_complete(si_ctlp, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan mutex_enter(&si_portp->siport_mutex);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_check_port_handles(si_portp) != DDI_SUCCESS) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_service_impact(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SERVICE_UNAFFECTED);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_schedule_port_initialize(si_ctlp, si_portp,
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan mutex_exit(&si_portp->siport_mutex);
0b0c3d307b4a6e7a73801251e4a6ab296acfc385johansen } else {
0b0c3d307b4a6e7a73801251e4a6ab296acfc385johansen /* Clear the interrupts */
0b0c3d307b4a6e7a73801251e4a6ab296acfc385johansen ddi_put32(si_ctlp->sictl_port_acc_handle,
0b0c3d307b4a6e7a73801251e4a6ab296acfc385johansen (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp, port)),
0b0c3d307b4a6e7a73801251e4a6ab296acfc385johansen port_intr_status & INTR_MASK);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note that we did not clear the interrupt for command
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * completion interrupt. Reading of slot_status takes care
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * of clearing the interrupt for command completion case.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_COMMAND_ERROR) {
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_schedule_intr_command_error(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_PORT_READY) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_port_ready(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_POWER_CHANGE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_pwr_change(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_PHYRDY_CHANGE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_phy_ready_change(si_ctlp, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_COMWAKE_RECEIVED) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_comwake_rcvd(si_ctlp, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_UNRECOG_FIS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_unrecognised_fis(si_ctlp, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_DEV_XCHANGED) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_dev_xchanged(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_8B10B_DECODE_ERROR) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_decode_err_threshold(si_ctlp, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_CRC_ERROR) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_crc_err_threshold(si_ctlp, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_HANDSHAKE_ERROR) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_handshake_err_threshold(si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (port_intr_status & INTR_SETDEVBITS_NOTIFY) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_intr_set_devbits_notify(si_ctlp, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_INTR_CLAIMED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt which indicates that one or more commands have successfully
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * completed.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Since we disabled W1C (write-one-to-clear) previously, mere reading
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * of slot_status register clears the interrupt. There is no need to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * explicitly clear the interrupt.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_command_complete(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t slot_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t finished_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int finished_slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt_t *satapkt;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_intr_command_complete enter", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!si_portp->siport_pending_tags) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Spurious interrupt. Nothing to be done.
0b0c3d307b4a6e7a73801251e4a6ab296acfc385johansen * The interrupt was cleared when slot_status was read.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp, "si3124: si_intr_command_complete: "
193974072f41a843678abf5f61979c748687e66bSherry Moore "pending_tags: %x, slot_status: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp->siport_pending_tags,
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf finished_tags = si_portp->siport_pending_tags &
193974072f41a843678abf5f61979c748687e66bSherry Moore ~slot_status & SI_SLOT_MASK;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf while (finished_tags) {
c03acfcad7780db4ddf763511a82026680b3b2c1ls
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf finished_slot = ddi_ffs(finished_tags) - 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (finished_slot == -1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt = si_portp->siport_slot_pkts[finished_slot];
c03acfcad7780db4ddf763511a82026680b3b2c1ls
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp, port,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek finished_slot);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, finished_slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(finished_tags, finished_slot);
a3f55fb1977ba058abdedc838f93a52aeff2d667xun ni - Sun Microsystems - Beijing China SENDUP_PACKET(si_portp, satapkt, SATA_PKT_COMPLETED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_PKTCOMP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "command_complete done: pend_tags: 0x%x, slot_status: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp->siport_pending_tags,
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * tidbit: no need to clear the interrupt since reading of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * slot_status automatically clears the interrupt in the case
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * of a successful command completion.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan/*
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan * Schedule a call to si_intr_command_error using a timeout to get it done
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan * off the interrupt thread.
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan */
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Loganstatic void
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logansi_schedule_intr_command_error(
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_ctl_state_t *si_ctlp,
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_port_state_t *si_portp,
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan int port)
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan{
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_event_arg_t *args;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan mutex_enter(&si_portp->siport_mutex);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan args = si_portp->siport_event_args;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan if (args->siea_ctlp != NULL) {
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan cmn_err(CE_WARN, "si_schedule_intr_command_error: "
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan "args->si_ctlp != NULL");
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan mutex_exit(&si_portp->siport_mutex);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan return;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan }
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan args->siea_ctlp = si_ctlp;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan args->siea_port = port;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan (void) timeout(si_do_intr_command_error, si_portp, 1);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan mutex_exit(&si_portp->siport_mutex);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan}
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan/*
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan * Called from timeout()
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan * Unpack the arguments and call si_intr_command_error()
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan */
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Loganstatic void
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logansi_do_intr_command_error(void *arg)
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan{
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_event_arg_t *args;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_ctl_state_t *si_ctlp;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_port_state_t *si_portp;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan int port;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan si_portp = arg;
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan mutex_enter(&si_portp->siport_mutex);
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan args = si_portp->siport_event_args;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_ctlp = args->siea_ctlp;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan port = args->siea_port;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan args->siea_ctlp = NULL; /* mark siport_event_args as free */
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan mutex_exit(&si_portp->siport_mutex);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan (void) si_intr_command_error(si_ctlp, si_portp, port);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan}
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt which indicates that a command did not complete successfully.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The port halts whenever a command error interrupt is received.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The only way to restart it is to reset or reinitialize the port
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * but such an operation throws away all the pending commands on
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We reset the device and mop the commands on the port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_command_error(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t command_error, slot_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t failed_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf command_error = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_intr_command_error: command_error: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore command_error);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Remember the slot_status since any of the recovery handler
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * can blow it away with reset operation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_log_error_message(si_ctlp, port, command_error);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (command_error) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_DEVICEERRROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_error_recovery_DEVICEERROR(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_SDBERROR:
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR, "SBD error");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_error_recovery_SDBERROR(si_ctlp, si_portp, port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_service_impact(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SERVICE_UNAFFECTED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_DATAFISERROR:
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan "Data FIS error");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_error_recovery_DATAFISERROR(si_ctlp, si_portp, port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_service_impact(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SERVICE_UNAFFECTED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_SENDFISERROR:
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan "Send FIS error");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_error_recovery_SENDFISERROR(si_ctlp, si_portp, port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_service_impact(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SERVICE_UNAFFECTED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf default:
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan "Unknown error");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_error_recovery_default(si_ctlp, si_portp, port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_service_impact(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SERVICE_UNAFFECTED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Compute the failed_tags by adding up the error tags.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The siport_err_tags_SDBERROR and siport_err_tags_nonSDBERROR
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * were filled in by the si_error_recovery_* routines.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf failed_tags = si_portp->siport_pending_tags &
193974072f41a843678abf5f61979c748687e66bSherry Moore (si_portp->siport_err_tags_SDBERROR |
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp->siport_err_tags_nonSDBERROR);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp, "si_intr_command_error: "
193974072f41a843678abf5f61979c748687e66bSherry Moore "err_tags_SDBERROR: 0x%x, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "err_tags_nonSDBERRROR: 0x%x, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "failed_tags: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp->siport_err_tags_SDBERROR,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp->siport_err_tags_nonSDBERROR,
193974072f41a843678abf5f61979c748687e66bSherry Moore failed_tags);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si3124: si_intr_command_error: "
193974072f41a843678abf5f61979c748687e66bSherry Moore "slot_status:0x%x, pending_tags: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp->siport_pending_tags);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan si_portp->mopping_in_progress++;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_mop_commands(si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port,
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status,
193974072f41a843678abf5f61979c748687e66bSherry Moore failed_tags,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, /* timedout_tags */
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, /* aborting_tags */
193974072f41a843678abf5f61979c748687e66bSherry Moore 0); /* reset_tags */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(si_portp->siport_pending_tags == 0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_SDBERROR = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_nonSDBERROR = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * There is a subtle difference between errors on a normal port and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a port-mult port. When an error happens on a normal port, the port
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is halted effectively until the port is reset or initialized.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * However, in port-mult port errors, port does not get halted since
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * other non-error devices behind the port multiplier can still
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * continue to operate. So we wait till all the commands are drained
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * instead of resetting it right away.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_recover_portmult_errors(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t command_error, slot_status, port_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int failed_slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_recover_portmult_errors: port: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Resume the port */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_SET_BITS_RESUME);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf command_error = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (command_error == CMD_ERR_SDBERROR) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_SDBERROR |= (0x1 << failed_slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now we drain the pending commands. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Since we have not yet returned DDI_INTR_CLAIMED,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * our interrupt handler is guaranteed not to be called again.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * So we need to check IS_ATTENTION_RAISED() for further
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * decisions.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This is a too big a delay for an interrupt context.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * But this is supposed to be a rare condition.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (IS_ATTENTION_RAISED(slot_status)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Resume again */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_SET_BITS_RESUME);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf command_error = ddi_get32(
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (command_error == CMD_ERR_SDBERROR) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_SDBERROR |=
193974072f41a843678abf5f61979c748687e66bSherry Moore (0x1 << failed_slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_nonSDBERROR |=
193974072f41a843678abf5f61979c748687e66bSherry Moore (0x1 << failed_slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_RECOVERPORTMULT) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are effectively timing out after 10 sec. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (slot_status & SI_SLOT_MASK);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The above loop can be improved for 3132 since we could obtain the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Port Multiplier Context of the device in error. Then we could
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * do a better job in filtering out commands for the device in error.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The loop could finish much earlier with such a logic.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Clear the RESUME bit. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_CLEAR_BITS_RESUME);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If we are connected to port multiplier, drain the non-failed devices.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Otherwise, we initialize the port (which effectively fails all the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * pending commands in the hope that sd would retry them later).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_error_recovery_DEVICEERROR(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t port_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int failed_slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_error_recovery_DEVICEERROR: port: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_recover_portmult_errors(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* In either case (port-mult or not), we reinitialize the port. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_initialize_port_wait_till_ready(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Handle exactly like DEVICEERROR. Remember the tags with SDBERROR
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to perform read_log_ext on them later. SDBERROR means that the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * error was for an NCQ command.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_error_recovery_SDBERROR(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t port_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int failed_slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si3124: si_error_recovery_SDBERROR: port: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_recover_portmult_errors(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_SDBERROR |= (0x1 << failed_slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* In either case (port-mult or not), we reinitialize the port. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_initialize_port_wait_till_ready(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Handle exactly like DEVICEERROR except resetting the port if there was
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * an NCQ command on the port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_error_recovery_DATAFISERROR(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t port_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int failed_slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si3124: si_error_recovery_DATAFISERROR: port: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* reset device if we were waiting for any ncq commands. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_pending_ncq_count) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore SI_DEVICE_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If we don't have any ncq commands pending, the rest of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the process is similar to the one for DEVICEERROR.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_error_recovery_DEVICEERROR(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We handle just like DEVICERROR except that we reset the device instead
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * of initializing the port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_error_recovery_SENDFISERROR(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t port_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int failed_slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si3124: si_error_recovery_SENDFISERROR: port: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_recover_portmult_errors(si_ctlp, si_portp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore SI_DEVICE_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The default behavior for all other errors is to reset the device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_error_recovery_default(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t port_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int failed_slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si3124: si_error_recovery_default: port: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore SI_DEVICE_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Read Log Ext with PAGE 10 to retrieve the error for an NCQ command.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic uint8_t
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_read_log_ext(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int slot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_prb_t *prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int i;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t slot_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t *prb_word_ptr;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t error;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_read_log_ext: port: %x", port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot = si_claim_free_slot(si_ctlp, si_portp, port);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (slot == SI_FAILURE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf prb = &(si_portp->siport_prbpool[slot]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bzero((void *)prb, sizeof (si_prb_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now fill the prb */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_COMMAND(prb->prb_fis, SATAC_READ_LOG_EXT);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_FIS_SECTOR(prb->prb_fis, SATA_LOG_PAGE_10);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* no real data transfer is involved */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_SGE_TRM(prb->prb_sge0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#if SI_DEBUG
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_debug_flags & SIDBG_DUMP_PRB) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int *ptr;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int j;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China ptr = (int *)(void *)prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmn_err(CE_WARN, "%x ", ptr[j]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* SI_DEBUG */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Deliver PRB */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Loop till the command is finished. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "looping read_log_ext slot_status: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are effectively timing out after 0.5 sec. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If we fail with the READ LOG EXT command, we need to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * initialize the port to clear the slot_status register.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We don't need to worry about any other valid commands
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * being thrown away because we are already in recovery
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * mode and READ LOG EXT is the only pending command.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_initialize_port_wait_till_ready(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "read_portmult_reg: loop count: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore loop_count);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The LRAM contains the the modified FIS.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Read the modified FIS to obtain the Error.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China prb_word_ptr = (uint32_t *)(void *)prb;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_check_port_handles(si_portp) != DDI_SUCCESS) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_service_impact(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_SERVICE_UNAFFECTED);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf error = GET_FIS_FEATURES(prb->prb_fis);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(si_portp->siport_pending_tags, slot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (error);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Dump the error message to the log.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_log_error_message(si_ctl_state_t *si_ctlp, int port, uint32_t command_error)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China#if SI_DEBUG
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China#ifndef __lock_lint
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China _NOTE(ARGUNUSED(si_ctlp))
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama _NOTE(ARGUNUSED(port))
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China#endif /* __lock_lint */
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf char *errstr;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (command_error) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_DEVICEERRROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "Standard Error: Error bit set in register - device"
193974072f41a843678abf5f61979c748687e66bSherry Moore " to host FIS";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_SDBERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "NCQ Error: Error bit set in register - device"
193974072f41a843678abf5f61979c748687e66bSherry Moore " to host FIS";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_DATAFISERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "Error in data FIS not detected by device";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_SENDFISERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "Initial command FIS transmission failed";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_INCONSISTENTSTATE:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "Inconsistency in protocol";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_DIRECTIONERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "DMA direction flag does not match the command";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_UNDERRUNERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "Run out of scatter gather entries while writing data";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_OVERRUNERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "Run out of scatter gather entries while reading data";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PACKETPROTOCOLERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "Packet protocol error";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PLDSGTERRORBOUNDARY:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "Scatter/gather table not on quadword boundary";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PLDSGTERRORTARETABORT:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "PCI(X) Target abort while fetching scatter/gather"
193974072f41a843678abf5f61979c748687e66bSherry Moore " table";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PLDSGTERRORMASTERABORT:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "PCI(X) Master abort while fetching scatter/gather"
193974072f41a843678abf5f61979c748687e66bSherry Moore " table";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PLDSGTERRORPCIERR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "PCI(X) parity error while fetching scatter/gather"
193974072f41a843678abf5f61979c748687e66bSherry Moore " table";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PLDCMDERRORBOUNDARY:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "PRB not on quadword boundary";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PLDCMDERRORTARGETABORT:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "PCI(X) Target abort while fetching PRB";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PLDCMDERRORMASTERABORT:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "PCI(X) Master abort while fetching PRB";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PLDCMDERORPCIERR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "PCI(X) parity error while fetching PRB";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PSDERRORTARGETABORT:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "PCI(X) Target abort during data transfer";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PSDERRORMASTERABORT:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "PCI(X) Master abort during data transfer";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_PSDERRORPCIERR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "PCI(X) parity error during data transfer";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf case CMD_ERR_SENDSERVICEERROR:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "FIS received while sending service FIS in"
193974072f41a843678abf5f61979c748687e66bSherry Moore " legacy queuing operation";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf default:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf errstr = "Unknown Error";
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_ERRS, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "command error: error: %s",
193974072f41a843678abf5f61979c748687e66bSherry Moore errstr);
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China#else
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China#ifndef __lock_lint
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama _NOTE(ARGUNUSED(si_ctlp))
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama _NOTE(ARGUNUSED(port))
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama _NOTE(ARGUNUSED(command_error))
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China#endif /* SI_DEBUG */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt which indicates that the Port Ready state has changed
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * from zero to one.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are not interested in this interrupt; we just log a debug message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_port_ready(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp, "si_intr_ready", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt which indicates that the port power management state
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * has been modified.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are not interested in this interrupt; we just log a debug message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_pwr_change(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp, "si_intr_pwr_change", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * Interrupt which indicates that the PHY state has changed either from
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Not-Ready to Ready or from Ready to Not-Ready.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_phy_ready_change(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_device_t sdevice;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t SStatus = 0; /* No dev present & PHY not established. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int dev_exists_now = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int dev_existed_previously = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_intr_phy_rdy_change", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((si_ctlp->sictl_sata_hba_tran == NULL) || (si_portp == NULL)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* the whole controller setup is not yet done. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* SStatus tells the presence of device. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_SSTATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf dev_exists_now =
193974072f41a843678abf5f61979c748687e66bSherry Moore (SSTATUS_GET_DET(SStatus) == SSTATUS_DET_DEVPRESENT_PHYONLINE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_port_type != PORT_TYPE_NODEV) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf dev_existed_previously = 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bzero((void *)&sdevice, sizeof (sata_device_t));
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China sdevice.satadev_addr.cport = (uint8_t)port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdevice.satadev_addr.pmport = PORTMULT_CONTROL_PORT;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* we don't have a way of determining the exact port-mult port. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdevice.satadev_addr.qual = SATA_ADDR_PMPORT;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
4372d277de71fc7c19cb9f41df9b8757b34e2cc5pawelw sdevice.satadev_state = SATA_STATE_READY; /* port state */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (dev_exists_now) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (dev_existed_previously) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Things are fine now. The loss was temporary. */
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "phyrdy: doing BOTH EVENTS TOGETHER", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_active) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_EVENT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "sending event: LINK_LOST & "
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "LINK_ESTABLISHED", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_event_notify(
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_sata_hba_tran->\
193974072f41a843678abf5f61979c748687e66bSherry Moore sata_tran_hba_dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore &sdevice,
193974072f41a843678abf5f61979c748687e66bSherry Moore SATA_EVNT_LINK_LOST|
193974072f41a843678abf5f61979c748687e66bSherry Moore SATA_EVNT_LINK_ESTABLISHED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* A new device has been detected. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_find_dev_signature(si_ctlp, si_portp, port,
193974072f41a843678abf5f61979c748687e66bSherry Moore PORTMULT_CONTROL_PORT);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "phyrdy: doing ATTACH event", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_active) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_EVENT, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "sending event up: LINK_ESTABLISHED", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_event_notify(
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_sata_hba_tran->\
193974072f41a843678abf5f61979c748687e66bSherry Moore sata_tran_hba_dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore &sdevice,
193974072f41a843678abf5f61979c748687e66bSherry Moore SATA_EVNT_LINK_ESTABLISHED);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else { /* No device exists now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (dev_existed_previously) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* An existing device is lost. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_active) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_EVENT, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "sending event up: LINK_LOST", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_event_notify(
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_sata_hba_tran->
193974072f41a843678abf5f61979c748687e66bSherry Moore sata_tran_hba_dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore &sdevice,
193974072f41a843678abf5f61979c748687e66bSherry Moore SATA_EVNT_LINK_LOST);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_port_type = PORT_TYPE_NODEV;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* spurious interrupt */
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "spurious phy ready interrupt", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt which indicates that a COMWAKE OOB signal has been decoded
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * on the receiver.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are not interested in this interrupt; we just log a debug message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_comwake_rcvd(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_intr_commwake_rcvd", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt which indicates that the F-bit has been set in SError
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Diag field.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are not interested in this interrupt; we just log a debug message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_unrecognised_fis(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_intr_unrecognised_fis", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt which indicates that the X-bit has been set in SError
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Diag field.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are not interested in this interrupt; we just log a debug message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_dev_xchanged(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_intr_dev_xchanged", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * Interrupt which indicates that the 8b/10b Decode Error counter has
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * exceeded the programmed non-zero threshold value.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are not interested in this interrupt; we just log a debug message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_decode_err_threshold(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_intr_err_threshold", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt which indicates that the CRC Error counter has exceeded the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * programmed non-zero threshold value.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are not interested in this interrupt; we just log a debug message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_crc_err_threshold(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_intr_crc_threshold", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt which indicates that the Handshake Error counter has
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * exceeded the programmed non-zero threshold value.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are not interested in this interrupt; we just log a debug message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_handshake_err_threshold(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_intr_handshake_err_threshold", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Interrupt which indicates that a "Set Device Bits" FIS has been
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * received with N-bit set in the control field.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are not interested in this interrupt; we just log a debug message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_intr_set_devbits_notify(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_intr_set_devbits_notify", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Enable the interrupts for a particular port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_enable_port_interrupts(si_ctl_state_t *si_ctlp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t mask;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* get the current settings first. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mask = ddi_get32(si_ctlp->sictl_global_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_enable_port_interrupts: current mask: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore mask);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* enable the bit for current port. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SET_BIT(mask, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* now use this mask to enable the interrupt. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_global_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
193974072f41a843678abf5f61979c748687e66bSherry Moore mask);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Enable interrupts for all the ports.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_enable_all_interrupts(si_ctl_state_t *si_ctlp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_enable_port_interrupts(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Disable interrupts for a particular port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_disable_port_interrupts(si_ctl_state_t *si_ctlp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t mask;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* get the current settings first. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mask = ddi_get32(si_ctlp->sictl_global_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* clear the bit for current port. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(mask, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* now use this mask to disable the interrupt. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_global_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
193974072f41a843678abf5f61979c748687e66bSherry Moore mask);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Disable interrupts for all the ports.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_disable_all_interrupts(si_ctl_state_t *si_ctlp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_disable_port_interrupts(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Fetches the latest sstatus, scontrol, serror, sactive registers
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * and stuffs them into sata_device_t structure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlffill_dev_sregisters(si_ctl_state_t *si_ctlp, int port, sata_device_t *satadev)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satadev->satadev_scr.sstatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SSTATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satadev->satadev_scr.serror = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SERROR(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satadev->satadev_scr.sactive = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SACTIVE(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satadev->satadev_scr.scontrol =
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SCONTROL(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_add_legacy_intrs() handles INTx and legacy interrupts.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_add_legacy_intrs(si_ctl_state_t *si_ctlp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf dev_info_t *devinfo = si_ctlp->sictl_devinfop;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int actual, count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int x, y, rc, inum = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp, "si_add_legacy_intrs", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* get number of interrupts. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &count);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rc != DDI_SUCCESS) || (count == 0)) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "ddi_intr_get_nintrs() failed, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "rc %d count %d\n", rc, count);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Allocate an array of interrupt handles. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_intr_size = count * sizeof (ddi_intr_handle_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_htable = kmem_zalloc(si_ctlp->sictl_intr_size, KM_SLEEP);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* call ddi_intr_alloc(). */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rc = ddi_intr_alloc(devinfo, si_ctlp->sictl_htable, DDI_INTR_TYPE_FIXED,
193974072f41a843678abf5f61979c748687e66bSherry Moore inum, count, &actual, DDI_INTR_ALLOC_STRICT);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rc != DDI_SUCCESS) || (actual == 0)) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "ddi_intr_alloc() failed, rc %d\n", rc);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (actual < count) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Requested: %d, Received: %d", count, actual);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (x = 0; x < actual; x++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_intr_cnt = actual;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Get intr priority. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_intr_get_pri(si_ctlp->sictl_htable[0],
193974072f41a843678abf5f61979c748687e66bSherry Moore &si_ctlp->sictl_intr_pri) != DDI_SUCCESS) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "ddi_intr_get_pri() failed", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (x = 0; x < actual; x++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Test for high level mutex. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_ctlp->sictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_add_legacy_intrs: Hi level intr not supported", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (x = 0; x < actual; x++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_htable, sizeof (ddi_intr_handle_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Call ddi_intr_add_handler(). */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (x = 0; x < actual; x++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_intr_add_handler(si_ctlp->sictl_htable[x], si_intr,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (caddr_t)si_ctlp, NULL) != DDI_SUCCESS) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "ddi_intr_add_handler() failed", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (y = 0; y < actual; y++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_htable,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_intr_size);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Call ddi_intr_enable() for legacy interrupts. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_enable(si_ctlp->sictl_htable[x]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_add_msictl_intrs() handles MSI interrupts.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_add_msi_intrs(si_ctl_state_t *si_ctlp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf dev_info_t *devinfo = si_ctlp->sictl_devinfop;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int count, avail, actual;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int x, y, rc, inum = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp, "si_add_msi_intrs", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* get number of interrupts. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_MSI, &count);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rc != DDI_SUCCESS) || (count == 0)) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "ddi_intr_get_nintrs() failed, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "rc %d count %d\n", rc, count);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* get number of available interrupts. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rc = ddi_intr_get_navail(devinfo, DDI_INTR_TYPE_MSI, &avail);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rc != DDI_SUCCESS) || (avail == 0)) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "ddi_intr_get_navail() failed, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "rc %d avail %d\n", rc, avail);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (avail < count) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "ddi_intr_get_nvail returned %d, navail() returned %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore count, avail);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Allocate an array of interrupt handles. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_intr_size = count * sizeof (ddi_intr_handle_t);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_htable = kmem_alloc(si_ctlp->sictl_intr_size, KM_SLEEP);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* call ddi_intr_alloc(). */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rc = ddi_intr_alloc(devinfo, si_ctlp->sictl_htable, DDI_INTR_TYPE_MSI,
193974072f41a843678abf5f61979c748687e66bSherry Moore inum, count, &actual, DDI_INTR_ALLOC_NORMAL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rc != DDI_SUCCESS) || (actual == 0)) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "ddi_intr_alloc() failed, rc %d\n", rc);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* use interrupt count returned */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (actual < count) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Requested: %d, Received: %d", count, actual);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_intr_cnt = actual;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Get priority for first msi, assume remaining are all the same.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_intr_get_pri(si_ctlp->sictl_htable[0],
193974072f41a843678abf5f61979c748687e66bSherry Moore &si_ctlp->sictl_intr_pri) != DDI_SUCCESS) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp, "ddi_intr_get_pri() failed", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Free already allocated intr. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (y = 0; y < actual; y++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Test for high level mutex. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_ctlp->sictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_add_msi_intrs: Hi level intr not supported", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Free already allocated intr. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (y = 0; y < actual; y++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_htable, sizeof (ddi_intr_handle_t));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Call ddi_intr_add_handler(). */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (x = 0; x < actual; x++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ddi_intr_add_handler(si_ctlp->sictl_htable[x], si_intr,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (caddr_t)si_ctlp, NULL) != DDI_SUCCESS) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ERRS, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "ddi_intr_add_handler() failed", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Free already allocated intr. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (y = 0; y < actual; y++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_htable,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_intr_size);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_get_cap(si_ctlp->sictl_htable[0],
193974072f41a843678abf5f61979c748687e66bSherry Moore &si_ctlp->sictl_intr_cap);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_ctlp->sictl_intr_cap & DDI_INTR_FLAG_BLOCK) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Call ddi_intr_block_enable() for MSI. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_block_enable(si_ctlp->sictl_htable,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_intr_cnt);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Call ddi_intr_enable() for MSI non block enable. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_enable(si_ctlp->sictl_htable[x]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (DDI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Removes the registered interrupts irrespective of whether they
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * were legacy or MSI.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_rem_intrs(si_ctl_state_t *si_ctlp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int x;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_INIT, si_ctlp, "si_rem_intrs entered", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Disable all interrupts. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((si_ctlp->sictl_intr_type == DDI_INTR_TYPE_MSI) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (si_ctlp->sictl_intr_cap & DDI_INTR_FLAG_BLOCK)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Call ddi_intr_block_disable(). */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_block_disable(si_ctlp->sictl_htable,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_intr_cnt);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_disable(si_ctlp->sictl_htable[x]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Call ddi_intr_remove_handler(). */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_remove_handler(si_ctlp->sictl_htable[x]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Resets either the port or the device connected to the port based on
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the flag variable.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The reset effectively throws away all the pending commands. So, the caller
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * has to make provision to handle the pending commands.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * After the reset, we wait till the port is ready again.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note: Not port-mult aware.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_reset_dport_wait_till_ready(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int flag)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t port_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_device_t sdevice;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t SStatus;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t SControl;
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek uint32_t port_intr_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf _NOTE(ASSUMING_PROTECTED(si_portp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (flag == SI_PORT_RESET) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_SET_BITS_PORT_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Port reset is not self clearing. So clear it now. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_CLEAR_BITS_PORT_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Reset the device. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_SET_BITS_DEV_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * tidbit: this bit is self clearing; so there is no need
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * for manual clear as we did for port reset.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Set the reset in progress flag */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(flag & SI_RESET_NO_EVENTS_UP)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp->siport_reset_in_progress = 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Every reset needs a PHY initialization.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The way to initialize the PHY is to write a 1 and then
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a 0 to DET field of SControl register.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Fetch the current SControl before writing the DET part with 1. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_SCONTROL(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
193974072f41a843678abf5f61979c748687e66bSherry Moore SControl);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now fetch the SControl again and rewrite the DET part with 0 */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_SCONTROL(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
193974072f41a843678abf5f61979c748687e66bSherry Moore SControl);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * PHY may be initialized by now. Check the DET field of SStatus
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to determine if there is a device present.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The DET field is valid only if IPM field indicates that
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the interface is in active state.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_SSTATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (SSTATUS_GET_IPM(SStatus) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_IPM_INTERFACE_ACTIVE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If the interface is not active, the DET field
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is considered not accurate. So we want to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * continue looping.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SSTATUS_SET_DET(SStatus, SSTATUS_DET_NODEV_NOPHY);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_SSTATUS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are effectively timing out after 0.1 sec. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (SSTATUS_GET_DET(SStatus) != SSTATUS_DET_DEVPRESENT_PHYONLINE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_reset_dport_wait_till_ready: loop count: %d, \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SStatus: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore loop_count,
193974072f41a843678abf5f61979c748687e66bSherry Moore SStatus);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now check for port readiness. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_PORTREADY) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are effectively timing out after 0.5 sec. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (!(port_status & PORT_STATUS_BITS_PORT_READY));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_reset_dport_wait_till_ready: loop count: %d, \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status: 0x%x, SStatus: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore loop_count,
193974072f41a843678abf5f61979c748687e66bSherry Moore port_status,
193974072f41a843678abf5f61979c748687e66bSherry Moore SStatus);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Indicate to the framework that a reset has happened. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(flag & SI_RESET_NO_EVENTS_UP)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf bzero((void *)&sdevice, sizeof (sata_device_t));
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China
0cfc6e4a9f5ce7c0aa92399e218a7e1ab2000715xun ni - Sun Microsystems - Beijing China sdevice.satadev_addr.cport = (uint8_t)port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdevice.satadev_addr.pmport = PORTMULT_CONTROL_PORT;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdevice.satadev_addr.qual = SATA_ADDR_DPMPORT;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdevice.satadev_state = SATA_DSTATE_RESET |
193974072f41a843678abf5f61979c748687e66bSherry Moore SATA_DSTATE_PWR_ACTIVE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_ctlp->sictl_sata_hba_tran) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_event_notify(
193974072f41a843678abf5f61979c748687e66bSherry Moore si_ctlp->sictl_sata_hba_tran->sata_tran_hba_dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore &sdevice,
193974072f41a843678abf5f61979c748687e66bSherry Moore SATA_EVNT_DEVICE_RESET);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_EVENT, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "sending event up: SATA_EVNT_RESET", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((SSTATUS_GET_IPM(SStatus) == SSTATUS_IPM_INTERFACE_ACTIVE) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (SSTATUS_GET_DET(SStatus) ==
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* The interface is active and the device is present */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(port_status & PORT_STATUS_BITS_PORT_READY)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* But the port is is not ready for some reason */
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_reset_dport_wait_till_ready failed", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek /*
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek * For some reason, we are losing the interrupt enablement after
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek * any reset condition. So restore them back now.
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek */
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INIT, si_portp,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek "current interrupt enable set: 0x%x",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek ddi_get32(si_ctlp->sictl_port_acc_handle,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port)));
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek ddi_put32(si_ctlp->sictl_port_acc_handle,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port),
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek (INTR_COMMAND_COMPLETE |
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek INTR_COMMAND_ERROR |
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek INTR_PORT_READY |
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek INTR_POWER_CHANGE |
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek INTR_PHYRDY_CHANGE |
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek INTR_COMWAKE_RECEIVED |
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek INTR_UNRECOG_FIS |
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek INTR_DEV_XCHANGED |
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek INTR_SETDEVBITS_NOTIFY));
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek si_enable_port_interrupts(si_ctlp, port);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek /*
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek * make sure interrupts are cleared
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek */
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek ddi_put32(si_ctlp->sictl_port_acc_handle,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek port)),
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek port_intr_status & INTR_MASK);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_reset_dport_wait_till_ready returning success", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan/*
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan * Schedule an initialization of the port using a timeout to get it done
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan * off an interrupt thread.
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan *
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan * WARNING, WARNING: The caller is expected to obtain the siport_mutex
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan * before calling us.
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan */
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Loganstatic void
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logansi_schedule_port_initialize(
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_ctl_state_t *si_ctlp,
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_port_state_t *si_portp,
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan int port)
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan{
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_event_arg_t *args;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan ASSERT(mutex_owned(&si_portp->siport_mutex));
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan args = si_portp->siport_event_args;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan if (args->siea_ctlp != NULL) {
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan cmn_err(CE_WARN, "si_schedule_port_initialize: "
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan "args->si_ctlp != NULL");
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan return;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan }
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan args->siea_ctlp = si_ctlp;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan args->siea_port = port;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan (void) timeout(si_do_initialize_port, si_portp, 1);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan}
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan/*
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan * Called from timeout()
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan * Unpack the arguments and call si_initialize_port_wait_till_ready()
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan */
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Loganstatic void
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logansi_do_initialize_port(void *arg)
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan{
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_event_arg_t *args;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_ctl_state_t *si_ctlp;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_port_state_t *si_portp;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan int port;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan si_portp = arg;
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan mutex_enter(&si_portp->siport_mutex);
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan args = si_portp->siport_event_args;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan si_ctlp = args->siea_ctlp;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan port = args->siea_port;
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan args->siea_ctlp = NULL; /* mark siport_event_args as free */
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan (void) si_initialize_port_wait_till_ready(si_ctlp, port);
6d0510ca167f2f1288adbced7a0c9b1be3f6058aMark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan mutex_exit(&si_portp->siport_mutex);
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan}
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
832d3fc2356e1dd511d8544e9f5d4ef5d91f36b6Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Initializes the port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Initialization effectively throws away all the pending commands on
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the port. So, the caller has to make provision to handle the pending
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * commands.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * After the port initialization, we wait till the port is ready again.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * WARNING, WARNING: The caller is expected to obtain the siport_mutex
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before calling us.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_initialize_port_wait_till_ready(si_ctl_state_t *si_ctlp, int port)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t port_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t SStatus;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Initialize the port. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_put32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
193974072f41a843678abf5f61979c748687e66bSherry Moore PORT_CONTROL_SET_BITS_PORT_INITIALIZE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait until Port Ready */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf loop_count = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf do {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_STATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (loop_count++ > SI_POLLRATE_PORTREADY) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INTR, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_initialize_port_wait is timing out: "
193974072f41a843678abf5f61979c748687e66bSherry Moore "port_status: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore port_status);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We are effectively timing out after 0.5 sec. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Wait for 10 millisec */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#ifndef __lock_lint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf delay(SI_10MS_TICKS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* __lock_lint */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } while (!(port_status & PORT_STATUS_BITS_PORT_READY));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_POLL_LOOP, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_initialize_port_wait_till_ready: loop count: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore loop_count);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)PORT_SSTATUS(si_ctlp, port));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((SSTATUS_GET_IPM(SStatus) == SSTATUS_IPM_INTERFACE_ACTIVE) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (SSTATUS_GET_DET(SStatus) ==
193974072f41a843678abf5f61979c748687e66bSherry Moore SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* The interface is active and the device is present */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(port_status & PORT_STATUS_BITS_PORT_READY)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* But the port is is not ready for some reason */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_FAILURE);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (SI_SUCCESS);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * si_watchdog_handler() calls us if it detects that there are some
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * commands which timed out. We recalculate the timed out commands once
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * again since some of them may have finished recently.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_timeout_pkts(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctl_state_t *si_ctlp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t timedout_tags)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t slot_status;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t finished_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_TIMEOUT, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_timeout_pkts entry", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan si_portp->mopping_in_progress++;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Initialize the controller. The only way to timeout the commands
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is to reset or initialize the controller. We mop commands after
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the initialization.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) si_initialize_port_wait_till_ready(si_ctlp, port);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Recompute the timedout tags since some of them may have finished
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * meanwhile.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf finished_tags = si_portp->siport_pending_tags &
193974072f41a843678abf5f61979c748687e66bSherry Moore ~slot_status & SI_SLOT_MASK;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf timedout_tags &= ~finished_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_TIMEOUT, si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "si_timeout_pkts: finished: %x, timeout: %x",
193974072f41a843678abf5f61979c748687e66bSherry Moore finished_tags,
193974072f41a843678abf5f61979c748687e66bSherry Moore timedout_tags);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_mop_commands(si_ctlp,
193974072f41a843678abf5f61979c748687e66bSherry Moore si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore port,
193974072f41a843678abf5f61979c748687e66bSherry Moore slot_status,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, /* failed_tags */
193974072f41a843678abf5f61979c748687e66bSherry Moore timedout_tags,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, /* aborting_tags */
193974072f41a843678abf5f61979c748687e66bSherry Moore 0); /* reset_tags */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Watchdog handler kicks in every 5 seconds to timeout any commands pending
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * for long time.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsi_watchdog_handler(si_ctl_state_t *si_ctlp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t pending_tags = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t timedout_tags = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_port_state_t *si_portp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int port;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int tmpslot;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt_t *satapkt;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* max number of cycles this packet should survive */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int max_life_cycles;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* how many cycles this packet survived so far */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int watched_cycles;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ENTRY, si_ctlp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "si_watchdog_handler entered", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_portp = si_ctlp->sictl_ports[port];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp == NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf continue;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (si_portp->siport_port_type == PORT_TYPE_NODEV) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf continue;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan /* Skip the check for those ports in error recovery */
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan if (si_portp->mopping_in_progress > 0) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_INFO, si_portp,
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan "si_watchdog_handler: port %d mopping "
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan "in progress, so just return", port);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan mutex_exit(&si_portp->siport_mutex);
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan continue;
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan }
cf6ed80965aca8bcea908933e1630401d69e7b03Mark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf pending_tags = si_portp->siport_pending_tags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf timedout_tags = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf while (pending_tags) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf tmpslot = ddi_ffs(pending_tags) - 1;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (tmpslot == -1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf break;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt = si_portp->siport_slot_pkts[tmpslot];
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((satapkt != NULL) && satapkt->satapkt_time) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are overloading satapkt_hba_driver_private
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * with watched_cycle count.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If a packet has survived for more than it's
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * max life cycles, it is a candidate for time
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * out.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf watched_cycles = (int)(intptr_t)
193974072f41a843678abf5f61979c748687e66bSherry Moore satapkt->satapkt_hba_driver_private;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf watched_cycles++;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf max_life_cycles = (satapkt->satapkt_time +
193974072f41a843678abf5f61979c748687e66bSherry Moore si_watchdog_timeout - 1) /
193974072f41a843678abf5f61979c748687e66bSherry Moore si_watchdog_timeout;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (watched_cycles > max_life_cycles) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf timedout_tags |= (0x1 << tmpslot);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_TIMEOUT,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama si_portp,
193974072f41a843678abf5f61979c748687e66bSherry Moore "watchdog: timedout_tags: 0x%x",
193974072f41a843678abf5f61979c748687e66bSherry Moore timedout_tags);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf satapkt->satapkt_hba_driver_private =
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)(intptr_t)watched_cycles;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf CLEAR_BIT(pending_tags, tmpslot);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (timedout_tags) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_timeout_pkts(si_ctlp, si_portp, port, timedout_tags);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_portp->siport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Reinstall the watchdog timeout handler. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(si_ctlp->sictl_flags & SI_NO_TIMEOUTS)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf si_ctlp->sictl_timeout_id =
193974072f41a843678abf5f61979c748687e66bSherry Moore timeout((void (*)(void *))si_watchdog_handler,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)si_ctlp, si_watchdog_tick);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_ctlp->sictl_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan/*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * FMA Functions
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan/*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * The IO fault service error handling callback function
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan/*ARGSUSED*/
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic int
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logansi_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan{
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * as the driver can always deal with an error in any dma or
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * access handle, we can just return the fme_status value.
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan pci_ereport_post(dip, err, NULL);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (err->fme_status);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan}
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan/*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * si_fm_init - initialize fma capabilities and register with IO
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * fault services.
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic void
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logansi_fm_init(si_ctl_state_t *si_ctlp)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan{
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * Need to change iblock to priority for new MSI intr
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_iblock_cookie_t fm_ibc;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /* Only register with IO Fault Services if we have some capability */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (si_ctlp->fm_capabilities) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /* Adjust access and dma attributes for FMA */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan accattr.devacc_attr_access = DDI_FLAGERR_ACC;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan prb_sgt_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan buffer_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * Register capabilities with IO Fault Services.
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * fm_capabilities will be updated to indicate
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * capabilities actually supported (not requested.)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_init(si_ctlp->sictl_devinfop, &si_ctlp->fm_capabilities,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan &fm_ibc);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (si_ctlp->fm_capabilities == DDI_FM_NOT_CAPABLE)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan cmn_err(CE_WARN, "si_fm_init: ddi_fm_init fail");
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * Initialize pci ereport capabilities if ereport
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * capable (should always be.)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities) ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan pci_ereport_setup(si_ctlp->sictl_devinfop);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * Register error callback if error callback capable.
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_handler_register(si_ctlp->sictl_devinfop,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan si_fm_error_cb, (void *) si_ctlp);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan}
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan/*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * si_fm_fini - Releases fma capabilities and un-registers with IO
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * fault services.
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic void
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logansi_fm_fini(si_ctl_state_t *si_ctlp)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan{
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /* Only unregister FMA capabilities if registered */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (si_ctlp->fm_capabilities) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * Un-register error callback if error callback capable.
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_handler_unregister(si_ctlp->sictl_devinfop);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * Release any resources allocated by pci_ereport_setup()
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities) ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan pci_ereport_teardown(si_ctlp->sictl_devinfop);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /* Unregister from IO Fault Services */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_fini(si_ctlp->sictl_devinfop);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan /* Adjust access and dma attributes for FMA */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan accattr.devacc_attr_access = DDI_DEFAULT_ACC;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan prb_sgt_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan buffer_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan}
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic int
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logansi_check_acc_handle(ddi_acc_handle_t handle)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan{
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_error_t de;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ASSERT(handle != NULL);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (de.fme_status);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan}
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic int
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logansi_check_dma_handle(ddi_dma_handle_t handle)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan{
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_error_t de;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ASSERT(handle != NULL);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (de.fme_status);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan}
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic int
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logansi_check_ctl_handles(si_ctl_state_t *si_ctlp)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan{
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if ((si_check_acc_handle(si_ctlp->sictl_pci_conf_handle)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan != DDI_SUCCESS) ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan (si_check_acc_handle(si_ctlp->sictl_global_acc_handle)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan != DDI_SUCCESS) ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan (si_check_acc_handle(si_ctlp->sictl_port_acc_handle)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan != DDI_SUCCESS)) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (DDI_FAILURE);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (DDI_SUCCESS);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan}
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan/*
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * WARNING: The caller is expected to obtain the siport_mutex
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan * before calling us.
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan */
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic int
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logansi_check_port_handles(si_port_state_t *si_portp)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan{
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if ((si_check_dma_handle(si_portp->siport_prbpool_dma_handle)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan != DDI_SUCCESS) ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan (si_check_acc_handle(si_portp->siport_prbpool_acc_handle)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan != DDI_SUCCESS) ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan (si_check_dma_handle(si_portp->siport_sgbpool_dma_handle)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan != DDI_SUCCESS) ||
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan (si_check_acc_handle(si_portp->siport_sgbpool_acc_handle)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan != DDI_SUCCESS)) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (DDI_FAILURE);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan return (DDI_SUCCESS);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan}
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Loganstatic void
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logansi_fm_ereport(si_ctl_state_t *si_ctlp, char *detail, char *payload)
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan{
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan uint64_t ena;
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan char buf[FM_MAX_CLASS];
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ena = fm_ena_generate(0, FM_ENA_FMT1);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities)) {
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan ddi_fm_ereport_post(si_ctlp->sictl_devinfop, buf, ena,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan DDI_NOSLEEP,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan "detailed_err_type", DATA_TYPE_STRING, payload,
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan NULL);
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan }
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan}
ab0d082f1ff5e05e86ea99a5672d8c466563280dMark Logan
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Logs the message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Ramasi_log(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, char *fmt, ...)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf{
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf va_list ap;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&si_log_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf va_start(ap, fmt);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama if (si_portp == NULL && si_ctlp == NULL) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama sata_vtrace_debug(NULL, fmt, ap);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama va_end(ap);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama mutex_exit(&si_log_mutex);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama return;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf }
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama if (si_portp == NULL && si_ctlp != NULL) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama sata_vtrace_debug(si_ctlp->sictl_devinfop, fmt, ap);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama va_end(ap);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama mutex_exit(&si_log_mutex);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama return;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama }
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama /*
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama * si_portp is not NULL, but si_ctlp might be.
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama * Reference si_portp for both port and dip.
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama */
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama (void) snprintf(si_log_buf, SI_LOGBUF_LEN, "port%d: %s",
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama si_portp->siport_port_num, fmt);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama if (si_portp->siport_ctlp == NULL) {
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama sata_vtrace_debug(NULL, si_log_buf, ap);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama va_end(ap);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama mutex_exit(&si_log_mutex);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama return;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama }
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama sata_vtrace_debug(si_portp->siport_ctlp->sictl_devinfop,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama si_log_buf, ap);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama va_end(ap);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&si_log_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}
c03acfcad7780db4ddf763511a82026680b3b2c1ls
c03acfcad7780db4ddf763511a82026680b3b2c1lsstatic void
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Falteseksi_copy_out_regs(sata_cmd_t *scmd, si_ctl_state_t *si_ctlp, uint8_t port,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek uint8_t slot)
c03acfcad7780db4ddf763511a82026680b3b2c1ls{
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek uint32_t *fis_word_ptr;
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek si_prb_t *prb;
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek int i;
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek /*
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek * The LRAM contains the the modified FIS after command completion, so
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek * first copy it back to the in-core PRB pool. To save read cycles,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek * just copy over the FIS portion of the PRB pool.
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek */
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek prb = &si_ctlp->sictl_ports[port]->siport_prbpool[slot];
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek fis_word_ptr = (uint32_t *)(void *)(&prb->prb_fis);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek for (i = 0; i < (sizeof (fis_reg_h2d_t)/4); i++) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek fis_word_ptr[i] = ddi_get32(
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek si_ctlp->sictl_port_acc_handle,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek (uint32_t *)(PORT_LRAM(si_ctlp, port,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek slot) + i * 4 + 0x08));
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek /*
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek * always get the status register
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek */
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_status_reg = GET_FIS_COMMAND(prb->prb_fis);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek DTRACE_PROBE1(satacmd_status_reg, int, scmd->satacmd_status_reg);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (scmd->satacmd_flags.sata_copy_out_sec_count_msb) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_sec_count_msb =
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek GET_FIS_SECTOR_COUNT_EXP(prb->prb_fis);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek "copyout satacmd_sec_count_msb %x\n",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_sec_count_msb);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (scmd->satacmd_flags.sata_copy_out_lba_low_msb) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_low_msb = GET_FIS_SECTOR_EXP(prb->prb_fis);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "copyout satacmd_lba_low_msb %x\n",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_low_msb);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (scmd->satacmd_flags.sata_copy_out_lba_mid_msb) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_mid_msb = GET_FIS_CYL_LOW_EXP(prb->prb_fis);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "copyout satacmd_lba_mid_msb %x\n",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_mid_msb);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (scmd->satacmd_flags.sata_copy_out_lba_high_msb) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_high_msb = GET_FIS_CYL_HI_EXP(prb->prb_fis);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "copyout satacmd_lba_high_msb %x\n",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_high_msb);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (scmd->satacmd_flags.sata_copy_out_sec_count_lsb) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_sec_count_lsb =
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek GET_FIS_SECTOR_COUNT(prb->prb_fis);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek "copyout satacmd_sec_count_lsb %x\n",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_sec_count_lsb);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (scmd->satacmd_flags.sata_copy_out_lba_low_lsb) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_low_lsb = GET_FIS_SECTOR(prb->prb_fis);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "copyout satacmd_lba_low_lsb %x\n",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_low_lsb);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (scmd->satacmd_flags.sata_copy_out_lba_mid_lsb) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_mid_lsb = GET_FIS_CYL_LOW(prb->prb_fis);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "copyout satacmd_lba_mid_lsb %x\n",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_mid_lsb);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (scmd->satacmd_flags.sata_copy_out_lba_high_lsb) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_high_lsb = GET_FIS_CYL_HI(prb->prb_fis);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "copyout satacmd_lba_high_lsb %x\n",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_lba_high_lsb);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (scmd->satacmd_flags.sata_copy_out_device_reg) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_device_reg = GET_FIS_DEV_HEAD(prb->prb_fis);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "copyout satacmd_device_reg %x\n",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_device_reg);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek if (scmd->satacmd_flags.sata_copy_out_error_reg) {
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_error_reg = GET_FIS_FEATURES(prb->prb_fis);
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_P(SIDBG_VERBOSE, si_portp,
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama "copyout satacmd_error_reg %x\n",
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek scmd->satacmd_error_reg);
a599d311a6462df52df7ff31f2d39eb197f4aeb3Martin Faltesek }
c03acfcad7780db4ddf763511a82026680b3b2c1ls}
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China/*
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * This function clear the special port by send the PORT RESET
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * After reset was sent, all commands running on the port
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * is aborted
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China */
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing Chinastatic int
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing Chinasi_clear_port(si_ctl_state_t *si_ctlp, int port)
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China{
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China if (si_ctlp == NULL)
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China return (SI_FAILURE);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China /*
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * reset this port so that all existing command
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * is clear
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China */
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China ddi_put32(si_ctlp->sictl_port_acc_handle,
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China PORT_CONTROL_SET_BITS_PORT_RESET);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China /* Port reset is not self clearing. So clear it now. */
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China ddi_put32(si_ctlp->sictl_port_acc_handle,
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China PORT_CONTROL_CLEAR_BITS_PORT_RESET);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China return (SI_SUCCESS);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China}
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China/*
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * quiesce(9E) entry point.
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * This function is called when the system is single-threaded at high
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * PIL with preemption disabled. Therefore, this function must not be
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * blocked.
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China *
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * DDI_FAILURE indicates an error condition and should almost never happen.
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China */
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing Chinastatic int
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing Chinasi_quiesce(dev_info_t *dip)
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China{
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China si_ctl_state_t *si_ctlp;
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China int instance;
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China int port;
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China instance = ddi_get_instance(dip);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China si_ctlp = ddi_get_soft_state(si_statep, instance);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China if (si_ctlp == NULL)
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China return (DDI_FAILURE);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China
e57ece5b0297b7f73b98eb54349e9eaea4fbd619Praveen Kumar Dasaraju Rama SIDBG_C(SIDBG_ENTRY, si_ctlp, "si_quiesce enter", NULL);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China /*
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China * Disable all the interrupts before quiesce
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China */
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China si_disable_port_interrupts(si_ctlp, port);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China (void) si_clear_port(si_ctlp, port);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China }
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China return (DDI_SUCCESS);
2d9382f4b3cd608ff106d8258d53d4e6b3f6d7e7xun ni - Sun Microsystems - Beijing China}