508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * O.S : Solaris
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * FILE NAME : arcmsr.c
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * BY : Erich Chen, C.L. Huang
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Description: SCSI RAID Device Driver for
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * ARECA RAID Host adapter
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Copyright (C) 2002,2010 Areca Technology Corporation All rights reserved.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Copyright (C) 2002,2010 Erich Chen
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Web site: www.areca.com.tw
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * E-mail: erich@areca.com.tw; ching2048@areca.com.tw
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson *
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Redistribution and use in source and binary forms, with or without
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * modification, are permitted provided that the following conditions
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * are met:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * 1. Redistributions of source code must retain the above copyright
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * notice, this list of conditions and the following disclaimer.
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * 2. Redistributions in binary form must reproduce the above copyright
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * notice, this list of conditions and the following disclaimer in the
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * documentation and/or other materials provided with the distribution.
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * 3. The party using or redistributing the source code and binary forms
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * agrees to the disclaimer below and the terms and conditions set forth
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * herein.
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson *
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * SUCH DAMAGE.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *
ed632624009d91d344479bf05ec24b9e0772939bColin Yi * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Use is subject to license terms.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * This file and its contents are supplied under the terms of the
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Common Development and Distribution License ("CDDL"), version 1.0.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * You may only use this file in accordance with the terms of version
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * 1.0 of the CDDL.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * A full copy of the text of the CDDL should have accompanied this
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * source. A copy of the CDDL is also available via the Internet at
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * http://www.illumos.org/license/CDDL.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/types.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/ddidmareq.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/scsi/scsi.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/ddi.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/sunddi.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/file.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/disp.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/signal.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/debug.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/pci.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include <sys/policy.h>
ed632624009d91d344479bf05ec24b9e0772939bColin Yi#include <sys/atomic.h>
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson#include "arcmsr.h"
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_attach(dev_info_t *dev_info, ddi_attach_cmd_t cmd);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_cb_ioctl(dev_t dev, int ioctl_cmd, intptr_t arg,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int mode, cred_t *credp, int *rvalp);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_detach(dev_info_t *dev_info, ddi_detach_cmd_t cmd);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_reset(dev_info_t *resetdev, ddi_reset_cmd_t cmd);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_tran_reset(struct scsi_address *ap, int level);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_tran_getcap(struct scsi_address *ap, char *cap, int whom);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_tran_setcap(struct scsi_address *ap, char *cap, int value,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int whom);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_tran_tgt_init(dev_info_t *host_dev_info,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson dev_info_t *target_dev_info, scsi_hba_tran_t *hosttran,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct scsi_device *sd);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_tran_destroy_pkt(struct scsi_address *ap,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct scsi_pkt *pkt);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_tran_sync_pkt(struct scsi_address *ap,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct scsi_pkt *pkt);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic struct scsi_pkt *arcmsr_tran_init_pkt(struct scsi_address *ap,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int tgtlen, int flags, int (*callback)(), caddr_t arg);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int arcmsr_config_child(struct ACB *acb, struct scsi_device *sd,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_info_t **dipp);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
ed632624009d91d344479bf05ec24b9e0772939bColin Yistatic int arcmsr_config_lun(struct ACB *acb, uint16_t tgt, uint8_t lun,
ed632624009d91d344479bf05ec24b9e0772939bColin Yi dev_info_t **ldip);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t arcmsr_abort_host_command(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t arcmsr_get_echo_from_iop(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint_t arcmsr_intr_handler(caddr_t arg, caddr_t arg2);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_initialize(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_dma_alloc(struct ACB *acb,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct scsi_pkt *pkt, struct buf *bp, int flags, int (*callback)());
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int arcmsr_dma_move(struct ACB *acb,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct scsi_pkt *pkt, struct buf *bp);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_handle_iop_bus_hold(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_hbc_message_isr(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_pcidev_disattach(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_ccb_complete(struct CCB *ccb, int flag);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_iop_init(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_iop_parking(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*PRINTFLIKE3*/
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_log(struct ACB *acb, int level, char *fmt, ...);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*PRINTFLIKE2*/
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_warn(struct ACB *acb, char *fmt, ...);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_mutex_init(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_remove_intr(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_ccbs_timeout(void* arg);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_devMap_monitor(void* arg);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_pcidev_disattach(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_iop_message_read(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_free_ccb(struct CCB *ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_post_ioctldata2iop(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_report_sense_info(struct CCB *ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_init_list_head(struct list_head *list);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_enable_allintr(struct ACB *acb, uint32_t intmask_org);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_done4abort_postqueue(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_list_add_tail(kmutex_t *list_lock,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct list_head *new_one, struct list_head *head);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int arcmsr_name_node(dev_info_t *dip, char *name, int len);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int arcmsr_seek_cmd2abort(struct ACB *acb, struct scsi_pkt *abortpkt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int arcmsr_iop_message_xfer(struct ACB *acb, struct scsi_pkt *pkt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int arcmsr_post_ccb(struct ACB *acb, struct CCB *ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int arcmsr_parse_devname(char *devnm, int *tgt, int *lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int arcmsr_do_ddi_attach(dev_info_t *dev_info, int instance);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t arcmsr_iop_reset(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint32_t arcmsr_disable_allintr(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint32_t arcmsr_iop_confirm(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic struct CCB *arcmsr_get_freeccb(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_flush_hba_cache(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_flush_hbb_cache(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_flush_hbc_cache(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_stop_hba_bgrb(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_stop_hbb_bgrb(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_stop_hbc_bgrb(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_start_hba_bgrb(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_start_hbb_bgrb(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_start_hbc_bgrb(struct ACB *acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_mutex_destroy(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_polling_hba_ccbdone(struct ACB *acb, struct CCB *poll_ccb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_polling_hbb_ccbdone(struct ACB *acb, struct CCB *poll_ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void arcmsr_polling_hbc_ccbdone(struct ACB *acb, struct CCB *poll_ccb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void arcmsr_build_ccb(struct CCB *ccb);
ed632624009d91d344479bf05ec24b9e0772939bColin Yistatic int arcmsr_tran_bus_config(dev_info_t *parent, uint_t flags,
ed632624009d91d344479bf05ec24b9e0772939bColin Yi ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
ed632624009d91d344479bf05ec24b9e0772939bColin Yistatic int arcmsr_name_node(dev_info_t *dip, char *name, int len);
ed632624009d91d344479bf05ec24b9e0772939bColin Yistatic dev_info_t *arcmsr_find_child(struct ACB *acb, uint16_t tgt,
ed632624009d91d344479bf05ec24b9e0772939bColin Yi uint8_t lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic struct QBUFFER *arcmsr_get_iop_rqbuffer(struct ACB *acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int arcmsr_add_intr(struct ACB *, int);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void *arcmsr_soft_state = NULL;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic ddi_dma_attr_t arcmsr_dma_attr = {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DMA_ATTR_V0, /* ddi_dma_attr version */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 0, /* low DMA address range */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore 0xffffffffffffffffull, /* high DMA address range */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 0x00ffffff, /* DMA counter counter upper bound */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 1, /* DMA address alignment requirements */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DEFAULT_BURSTSIZE | BURST32 | BURST64, /* burst sizes */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 1, /* minimum effective DMA size */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ARCMSR_MAX_XFER_LEN, /* maximum DMA xfer size */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * The dma_attr_seg field supplies the limit of each Scatter/Gather
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * list element's "address+length". The Intel IOP331 can not use
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * segments over the 4G boundary due to segment boundary restrictions
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore 0xffffffff,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ARCMSR_MAX_SG_ENTRIES, /* scatter/gather list count */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore 1, /* device granularity */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DDI_DMA_FORCE_PHYSICAL /* Bus specific DMA flags */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson};
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic ddi_dma_attr_t arcmsr_ccb_attr = {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DMA_ATTR_V0, /* ddi_dma_attr version */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 0, /* low DMA address range */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 0xffffffff, /* high DMA address range */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 0x00ffffff, /* DMA counter counter upper bound */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 1, /* default byte alignment */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DEFAULT_BURSTSIZE | BURST32 | BURST64, /* burst sizes */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 1, /* minimum effective DMA size */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 0xffffffff, /* maximum DMA xfer size */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 0x00ffffff, /* max segment size, segment boundary restrictions */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 1, /* scatter/gather list count */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 1, /* device granularity */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DDI_DMA_FORCE_PHYSICAL /* Bus specific DMA flags */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson};
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic struct cb_ops arcmsr_cb_ops = {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson scsi_hba_open, /* open(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson scsi_hba_close, /* close(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* strategy(9E), returns ENXIO */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* print(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* dump(9E) Cannot be used as a dump device */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* read(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* write(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_cb_ioctl, /* ioctl(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* devmap(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* mmap(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* segmap(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson NULL, /* chpoll(9E) returns ENXIO */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* prop_op(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson NULL, /* streamtab(9S) */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore D_MP,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CB_REV,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* aread(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev /* awrite(9E) */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson};
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic struct dev_ops arcmsr_ops = {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DEVO_REV, /* devo_rev */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson 0, /* reference count */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nodev, /* getinfo */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nulldev, /* identify */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson nulldev, /* probe */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_attach, /* attach */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_detach, /* detach */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_reset, /* reset, shutdown, reboot notify */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &arcmsr_cb_ops, /* driver operations */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson NULL, /* bus operations */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore NULL /* power */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson};
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic struct modldrv arcmsr_modldrv = {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &mod_driverops, /* Type of module. This is a driver. */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "ARECA RAID Controller", /* module name, from arcmsr.h */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &arcmsr_ops, /* driver ops */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson};
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic struct modlinkage arcmsr_modlinkage = {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson MODREV_1,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &arcmsr_modldrv,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson NULL
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson};
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonint
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore_init(void)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int ret;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ret = ddi_soft_state_init(&arcmsr_soft_state, sizeof (struct ACB), 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (ret != 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (ret);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if ((ret = scsi_hba_init(&arcmsr_modlinkage)) != 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ddi_soft_state_fini(&arcmsr_soft_state);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (ret);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if ((ret = mod_install(&arcmsr_modlinkage)) != 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson scsi_hba_fini(&arcmsr_modlinkage);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (arcmsr_soft_state != NULL) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ddi_soft_state_fini(&arcmsr_soft_state);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (ret);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonint
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore_fini(void)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int ret;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ret = mod_remove(&arcmsr_modlinkage);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (ret == 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* if ret = 0 , said driver can remove */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson scsi_hba_fini(&arcmsr_modlinkage);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (arcmsr_soft_state != NULL) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ddi_soft_state_fini(&arcmsr_soft_state);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (ret);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonint
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore_info(struct modinfo *modinfop)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (mod_info(&arcmsr_modlinkage, modinfop));
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_attach(9E)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Description: Set up all device state and allocate data structures,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * mutexes, condition variables, etc. for device operation.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Set mt_attr property for driver to indicate MT-safety.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Add interrupts needed.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Input: dev_info_t *dev_info, ddi_attach_cmd_t cmd
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Output: Return DDI_SUCCESS if device is ready,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * else return DDI_FAILURE
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_attach(dev_info_t *dev_info, ddi_attach_cmd_t cmd)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_tran_t *hba_trans;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (cmd) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case DDI_ATTACH:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (arcmsr_do_ddi_attach(dev_info,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_get_instance(dev_info)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case DDI_RESUME:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * There is no hardware state to restart and no
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * timeouts to restart since we didn't DDI_SUSPEND with
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * active cmds or active timeouts We just need to
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * unblock waiting threads and restart I/O the code
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans = ddi_get_driver_private(dev_info);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (hba_trans == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb = hba_trans->tran_hba_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop_init(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* restart ccbs "timeout" watchdog */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_count = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_id = timeout(arcmsr_ccbs_timeout, (caddr_t)acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (ARCMSR_TIMEOUT_WATCH * drv_usectohz(1000000)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_sc_id = timeout(arcmsr_devMap_monitor,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (caddr_t)acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (ARCMSR_DEV_MAP_WATCH * drv_usectohz(1000000)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
ed632624009d91d344479bf05ec24b9e0772939bColin Yi}
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_detach(9E)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Description: Remove all device allocation and system resources, disable
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * device interrupt.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Input: dev_info_t *dev_info
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * ddi_detach_cmd_t cmd
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Output: Return DDI_SUCCESS if done,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * else returnDDI_FAILURE
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_detach(dev_info_t *dev_info, ddi_detach_cmd_t cmd) {
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int instance;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore instance = ddi_get_instance(dev_info);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb = ddi_get_soft_state(arcmsr_soft_state, instance);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb == NULL)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (cmd) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case DDI_DETACH:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->timeout_id != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) untimeout(acb->timeout_id);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_id = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->timeout_sc_id != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) untimeout(acb->timeout_sc_id);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_sc_id = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_pcidev_disattach(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Remove interrupt set up by ddi_add_intr */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_remove_intr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* unbind mapping object to handle */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_unbind_handle(acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Free ccb pool memory */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_mem_free(&acb->ccbs_acc_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Free DMA handle */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_regs_map_free(&acb->reg_mu_acc_handle0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (scsi_hba_detach(dev_info) != DDI_SUCCESS)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "Unable to detach instance cleanly "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "(should not happen)");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* free scsi_hba_transport from scsi_hba_tran_alloc */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_tran_free(acb->scsi_hba_transport);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_taskq_destroy(acb->taskq);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_prop_remove_all(dev_info);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_mutex_destroy(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pci_config_teardown(&acb->pci_acc_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_set_driver_private(dev_info, NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_soft_state_free(arcmsr_soft_state, instance);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case DDI_SUSPEND:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->timeout_id != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags |= ACB_F_SCSISTOPADAPTER;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) untimeout(acb->timeout_id);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) untimeout(acb->timeout_sc_id);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_id = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->timeout_sc_id != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags |= ACB_F_SCSISTOPADAPTER;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) untimeout(acb->timeout_sc_id);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_sc_id = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* disable all outbound interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) arcmsr_disable_allintr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* stop adapter background rebuild */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_stop_hba_bgrb(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hba_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_stop_hbb_bgrb(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hbb_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_stop_hbc_bgrb(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hbc_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_reset(dev_info_t *resetdev, ddi_reset_cmd_t cmd)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_tran_t *scsi_hba_transport;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore _NOTE(ARGUNUSED(cmd));
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_transport = ddi_get_driver_private(resetdev);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (scsi_hba_transport == NULL)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb = (struct ACB *)scsi_hba_transport->tran_hba_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_pcidev_disattach(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_cb_ioctl(dev_t dev, int ioctl_cmd, intptr_t arg, int mode,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cred_t *credp, int *rvalp)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CMD_MESSAGE_FIELD *pktioctlfld;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int retvalue = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int instance = MINOR2INST(getminor(dev));
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (instance < 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (ENXIO);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (secpolicy_sys_config(credp, B_FALSE) != 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (EPERM);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb = ddi_get_soft_state(arcmsr_soft_state, instance);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb == NULL)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (ENXIO);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld = kmem_zalloc(sizeof (struct CMD_MESSAGE_FIELD), KM_SLEEP);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->ioctl_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_copyin((void *)arg, pktioctlfld,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct CMD_MESSAGE_FIELD), mode) != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ENXIO;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto ioctl_out;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (memcmp(pktioctlfld->cmdmessage.Signature, "ARCMSR", 6) != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* validity check */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ENXIO;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto ioctl_out;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch ((unsigned int)ioctl_cmd) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_MESSAGE_READ_RQBUFFER:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *ver_addr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *pQbuffer, *ptmpQbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int32_t allxfer_len = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ver_addr = kmem_zalloc(MSGDATABUFLEN, KM_SLEEP);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ptmpQbuffer = ver_addr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while ((acb->rqbuf_firstidx != acb->rqbuf_lastidx) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (allxfer_len < (MSGDATABUFLEN - 1))) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* copy READ QBUFFER to srb */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pQbuffer = &acb->rqbuffer[acb->rqbuf_firstidx];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memcpy(ptmpQbuffer, pQbuffer, 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->rqbuf_firstidx++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* if last index number set it to 0 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->rqbuf_firstidx %= ARCMSR_MAX_QBUFFER;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ptmpQbuffer++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore allxfer_len++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct QBUFFER *prbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *pQbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *iop_data;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int32_t iop_len;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore prbuffer = arcmsr_get_iop_rqbuffer(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_data = (uint8_t *)prbuffer->data;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_len = (int32_t)prbuffer->data_len;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * this iop data does no chance to make me overflow
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * again here, so just do it
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while (iop_len > 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pQbuffer = &acb->rqbuffer[acb->rqbuf_lastidx];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memcpy(pQbuffer, iop_data, 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->rqbuf_lastidx++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* if last index number set it to 0 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->rqbuf_lastidx %= ARCMSR_MAX_QBUFFER;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_data++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_len--;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* let IOP know data has been read */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop_message_read(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memcpy(pktioctlfld->messagedatabuffer,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ver_addr, allxfer_len);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld->cmdmessage.Length = allxfer_len;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld->cmdmessage.ReturnCode =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_RETURNCODE_OK;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_copyout(pktioctlfld, (void *)arg,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ENXIO;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore kmem_free(ver_addr, MSGDATABUFLEN);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_MESSAGE_WRITE_WQBUFFER:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *ver_addr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int32_t my_empty_len, user_len;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int32_t wqbuf_firstidx, wqbuf_lastidx;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *pQbuffer, *ptmpuserbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ver_addr = kmem_zalloc(MSGDATABUFLEN, KM_SLEEP);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ptmpuserbuffer = ver_addr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore user_len = min(pktioctlfld->cmdmessage.Length,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore MSGDATABUFLEN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memcpy(ptmpuserbuffer,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld->messagedatabuffer, user_len);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * check ifdata xfer length of this request will overflow
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * my array qbuffer
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore wqbuf_lastidx = acb->wqbuf_lastidx;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore wqbuf_firstidx = acb->wqbuf_firstidx;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (wqbuf_lastidx != wqbuf_firstidx) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_post_ioctldata2iop(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld->cmdmessage.ReturnCode =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_RETURNCODE_ERROR;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore my_empty_len = (wqbuf_firstidx - wqbuf_lastidx - 1)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore & (ARCMSR_MAX_QBUFFER - 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (my_empty_len >= user_len) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while (user_len > 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* copy srb data to wqbuffer */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pQbuffer =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->wqbuffer[acb->wqbuf_lastidx];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memcpy(pQbuffer,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ptmpuserbuffer, 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->wqbuf_lastidx++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* iflast index number set it to 0 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->wqbuf_lastidx %=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MAX_QBUFFER;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ptmpuserbuffer++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore user_len--;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* post first Qbuffer */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->acb_flags &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ACB_F_MESSAGE_WQBUFFER_CLEARED) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_post_ioctldata2iop(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld->cmdmessage.ReturnCode =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_RETURNCODE_OK;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld->cmdmessage.ReturnCode =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_RETURNCODE_ERROR;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_copyout(pktioctlfld, (void *)arg,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ENXIO;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore kmem_free(ver_addr, MSGDATABUFLEN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_MESSAGE_CLEAR_RQBUFFER:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *pQbuffer = acb->rqbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop_message_read(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->rqbuf_firstidx = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->rqbuf_lastidx = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero(pQbuffer, ARCMSR_MAX_QBUFFER);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* report success */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld->cmdmessage.ReturnCode =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_RETURNCODE_OK;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_copyout(pktioctlfld, (void *)arg,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ENXIO;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_MESSAGE_CLEAR_WQBUFFER:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *pQbuffer = acb->wqbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop_message_read(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ACB_F_MESSAGE_WQBUFFER_READ);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->wqbuf_firstidx = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->wqbuf_lastidx = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero(pQbuffer, ARCMSR_MAX_QBUFFER);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* report success */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld->cmdmessage.ReturnCode =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_RETURNCODE_OK;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_copyout(pktioctlfld, (void *)arg,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ENXIO;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *pQbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop_message_read(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ACB_F_MESSAGE_RQBUFFER_CLEARED |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ACB_F_MESSAGE_WQBUFFER_READ);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->rqbuf_firstidx = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->rqbuf_lastidx = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->wqbuf_firstidx = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->wqbuf_lastidx = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pQbuffer = acb->rqbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero(pQbuffer, sizeof (struct QBUFFER));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pQbuffer = acb->wqbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero(pQbuffer, sizeof (struct QBUFFER));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* report success */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld->cmdmessage.ReturnCode =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_RETURNCODE_OK;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_copyout(pktioctlfld, (void *)arg,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ENXIO;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_MESSAGE_REQUEST_RETURN_CODE_3F:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pktioctlfld->cmdmessage.ReturnCode =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_RETURNCODE_3F;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_copyout(pktioctlfld, (void *)arg,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ENXIO;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Not supported: ARCMSR_MESSAGE_SAY_HELLO */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_MESSAGE_SAY_GOODBYE:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop_parking(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hba_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hbb_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hbc_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->ioctl_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore kmem_free(pktioctlfld, sizeof (struct CMD_MESSAGE_FIELD));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (scsi_hba_ioctl(dev, ioctl_cmd, arg, mode, credp,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rvalp));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoreioctl_out:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore kmem_free(pktioctlfld, sizeof (struct CMD_MESSAGE_FIELD));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->ioctl_mutex);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (retvalue);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_tran_tgt_init
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Description: Called when initializing a target device instance. If
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * no per-target initialization is required, the HBA
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * may leave tran_tgt_init to NULL
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Input:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * dev_info_t *host_dev_info,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * dev_info_t *target_dev_info,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * scsi_hba_tran_t *tran,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * struct scsi_device *sd
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return: DDI_SUCCESS if success, else return DDI_FAILURE
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * entry point enables the HBA to allocate and/or initialize any per-
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * target resources.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * It also enables the HBA to qualify the device's address as valid and
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * supportable for that particular HBA.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * By returning DDI_FAILURE, the instance of the target driver for that
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * device will not be probed or attached.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * This entry point is not required, and if none is supplied,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * the framework will attempt to probe and attach all possible instances
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * of the appropriate target drivers.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_tran_tgt_init(dev_info_t *host_dev_info, dev_info_t *target_dev_info,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_tran_t *tran, struct scsi_device *sd)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint16_t target;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb = tran->tran_hba_private;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore _NOTE(ARGUNUSED(tran, target_dev_info, host_dev_info))
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore target = sd->sd_address.a_target;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore lun = sd->sd_address.a_lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((target >= ARCMSR_MAX_TARGETID) || (lun >= ARCMSR_MAX_TARGETLUN)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ndi_dev_is_persistent_node(target_dev_info) == 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * If no persistent node exist, we don't allow .conf node
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * to be created.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_find_child(acb, target, lun) != NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((ndi_merge_node(target_dev_info,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_name_node) != DDI_SUCCESS)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_tran_getcap(9E)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Description: Get the capability named, and returnits value.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return Values: current value of capability, ifdefined
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * -1 ifcapability is not defined
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * ------------------------------------------------------
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Common Capability Strings Array
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * ------------------------------------------------------
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_DMA_MAX 0
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_MSG_OUT 1
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_DISCONNECT 2
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_SYNCHRONOUS 3
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_WIDE_XFER 4
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_PARITY 5
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_INITIATOR_ID 6
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_UNTAGGED_QING 7
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_TAGGED_QING 8
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_ARQ 9
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_LINKED_CMDS 10 a
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_SECTOR_SIZE 11 b
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_TOTAL_SECTORS 12 c
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_GEOMETRY 13 d
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_RESET_NOTIFICATION 14 e
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_QFULL_RETRIES 15 f
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_QFULL_RETRY_INTERVAL 16 10
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_SCSI_VERSION 17 11
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_INTERCONNECT_TYPE 18 12
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * #define SCSI_CAP_LUN_RESET 19 13
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_tran_getcap(struct scsi_address *ap, char *cap, int whom)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int capability = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb = (struct ACB *)ap->a_hba_tran->tran_hba_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (cap == NULL || whom == 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->devstate[ap->a_target][ap->a_lun] == ARECA_RAID_GONE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (-1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (scsi_hba_lookup_capstr(cap)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_MSG_OUT:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_DISCONNECT:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_WIDE_XFER:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_TAGGED_QING:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_UNTAGGED_QING:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_PARITY:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_ARQ:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore capability = 1;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_SECTOR_SIZE:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore capability = ARCMSR_DEV_SECTOR_SIZE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_DMA_MAX:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Limit to 16MB max transfer */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore capability = ARCMSR_MAX_XFER_LEN;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_INITIATOR_ID:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore capability = ARCMSR_SCSI_INITIATOR_ID;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_GEOMETRY:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* head , track , cylinder */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore capability = (255 << 16) | 63;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore capability = -1;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (capability);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_tran_setcap(9E)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Description: Set the specific capability.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return Values: 1 - capability exists and can be set to new value
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * 0 - capability could not be set to new value
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * -1 - no such capability
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_tran_setcap(struct scsi_address *ap, char *cap, int value, int whom)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore _NOTE(ARGUNUSED(value))
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int supported = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb = (struct ACB *)ap->a_hba_tran->tran_hba_private;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (cap == NULL || whom == 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (-1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->devstate[ap->a_target][ap->a_lun] == ARECA_RAID_GONE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (-1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (supported = scsi_hba_lookup_capstr(cap)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_ARQ: /* 9 auto request sense */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_UNTAGGED_QING: /* 7 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_TAGGED_QING: /* 8 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* these are always on, and cannot be turned off */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore supported = (value == 1) ? 1 : 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_TOTAL_SECTORS: /* c */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore supported = 1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_DISCONNECT: /* 2 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_WIDE_XFER: /* 4 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_INITIATOR_ID: /* 6 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_DMA_MAX: /* 0 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_MSG_OUT: /* 1 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_PARITY: /* 5 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_LINKED_CMDS: /* a */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_RESET_NOTIFICATION: /* e */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSI_CAP_SECTOR_SIZE: /* b */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* these are not settable */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore supported = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore supported = -1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (supported);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_tran_init_pkt
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return Values: pointer to scsi_pkt, or NULL
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Description: simultaneously allocate both a scsi_pkt(9S) structure and
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * DMA resources for that pkt.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Called by kernel on behalf of a target driver
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * calling scsi_init_pkt(9F).
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Refer to tran_init_pkt(9E) man page
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Context: Can be called from different kernel process threads.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Can be called by interrupt thread.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Allocates SCSI packet and DMA resources
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic struct
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorescsi_pkt *arcmsr_tran_init_pkt(struct scsi_address *ap,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore register struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int tgtlen, int flags, int (*callback)(), caddr_t arg)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ARCMSR_CDB *arcmsr_cdb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int old_pkt_flag;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb = (struct ACB *)ap->a_hba_tran->tran_hba_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->acb_flags & ACB_F_BUS_RESET) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (NULL);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (pkt == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* get free CCB */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_sync(acb->ccbs_pool_handle, 0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SYNC_FORKERNEL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = arcmsr_get_freeccb(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb == (struct CCB *)NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (statuslen < sizeof (struct scsi_arq_status)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore statuslen = sizeof (struct scsi_arq_status);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt = scsi_hba_pkt_alloc(acb->dev_info, ap, cmdlen,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore statuslen, tgtlen, sizeof (void *), callback, arg);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (pkt == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "scsi pkt allocation failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_free_ccb(ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Initialize CCB */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt = pkt;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dma_handle = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* record how many sg are needed to xfer on this pkt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_ncookies = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* record how many sg we got from this window */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_cookie = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* record how many windows have partial dma map set */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_nwin = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* record current sg window position */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_curwin = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dma_len = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dma_offset = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->resid_dmacookie.dmac_size = 0;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * we will still use this point for we want to fake some
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * information in tran_start
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->bp = bp;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Initialize arcmsr_cdb */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb = &ccb->arcmsr_cdb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero(arcmsr_cdb, sizeof (struct ARCMSR_CDB));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->Bus = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->Function = 1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->LUN = ap->a_lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->TargetID = ap->a_target;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->CdbLength = (uint8_t)cmdlen;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->Context = (uintptr_t)arcmsr_cdb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Fill in the rest of the structure */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_ha_private = ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_address = *ap;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_comp = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_flags = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_time = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_resid = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_statistics = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_reason = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore old_pkt_flag = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = pkt->pkt_ha_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state & ARCMSR_ABNORMAL_MASK) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!(ccb->ccb_state & ARCMSR_CCB_BACK)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * you cannot update CdbLength with cmdlen here, it would
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * cause a data compare error
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state = ARCMSR_CCB_UNBUILD;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore old_pkt_flag = 1;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Second step : dma allocation/move */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (bp && bp->b_bcount != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * system had a lot of data trunk need to xfer, from...20 byte
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * to 819200 byte.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * arcmsr_dma_alloc will get pkt_dma_handle (not null) until
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * this lot of data trunk xfer done this mission will be done
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * by some of continue READ or WRITE scsi command, till this
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * lot of data trunk xfer completed.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * arcmsr_dma_move do the action repeatedly, and use the same
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * ccb till this lot of data trunk xfer complete notice.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * when after the arcmsr_tran_init_pkt returns the solaris
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * kernel is by your pkt_resid and its b_bcount to give you
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * which type of scsi command descriptor to implement the
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * length of folowing arcmsr_tran_start scsi cdb (data length)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Each transfer should be aligned on a 512 byte boundary
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->pkt_dma_handle == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_dma_alloc(acb, pkt, bp, flags, callback) ==
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_FAILURE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * the HBA driver is unable to allocate DMA
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * resources, it must free the allocated
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * scsi_pkt(9S) before returning
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "dma allocation failure");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (old_pkt_flag == 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "dma "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "allocation failed to free "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "scsi hba pkt");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_free_ccb(ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_pkt_free(ap, pkt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* DMA resources to next DMA window, for old pkt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_dma_move(acb, pkt, bp) == DDI_FAILURE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "dma move failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_resid = 0;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (pkt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_tran_start(9E)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Description: Transport the command in pktp to the target device.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * The command is not finished when this returns, only
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * sent to the target; arcmsr_intr_handler will call
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * scsi_hba_pkt_comp(pktp) when the target device has done.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Input: struct scsi_address *ap, struct scsi_pkt *pktp
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Output: TRAN_ACCEPT if pkt is OK and not driver not busy
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * TRAN_BUSY if driver is
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * TRAN_BADPKT if pkt is invalid
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int target = ap->a_target;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int lun = ap->a_lun;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb = (struct ACB *)ap->a_hba_tran->tran_hba_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = pkt->pkt_ha_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *pkt->pkt_scbp = STATUS_GOOD; /* clear arq scsi_status */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((ccb->ccb_flags & CCB_FLAG_DMAVALID) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (ccb->ccb_flags & DDI_DMA_CONSISTENT))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_sync(ccb->pkt_dma_handle, 0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SYNC_FORDEV);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state == ARCMSR_CCB_UNBUILD)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_build_ccb(ccb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->acb_flags & ACB_F_BUS_RESET) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_reason = CMD_RESET;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_statistics |= STAT_BUS_RESET;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore STATE_SENT_CMD | STATE_GOT_STATUS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((ccb->ccb_flags & CCB_FLAG_DMACONSISTENT) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (pkt->pkt_state & STATE_XFERRED_DATA))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_sync(ccb->pkt_dma_handle,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore 0, 0, DDI_DMA_SYNC_FORCPU);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_pkt_comp(pkt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRAN_ACCEPT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* IMPORTANT: Target 16 is a virtual device for iop message transfer */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (target == 16) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct buf *bp = ccb->bp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t scsicmd = pkt->pkt_cdbp[0];
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (scsicmd) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCMD_INQUIRY: {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (lun != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_TIMEOUT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_statistics |= STAT_TIMEOUT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccb_complete(ccb, 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRAN_ACCEPT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (bp && bp->b_un.b_addr && bp->b_bcount) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t inqdata[36];
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* The EVDP and pagecode is not supported */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (pkt->pkt_cdbp[1] || pkt->pkt_cdbp[2]) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore inqdata[1] = 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore inqdata[2] = 0x00;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Periph Qualifier & Periph Dev Type */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore inqdata[0] = DTYPE_PROCESSOR;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* rem media bit & Dev Type Modifier */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore inqdata[1] = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* ISO, ECMA, & ANSI versions */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore inqdata[2] = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore inqdata[3] = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* length of additional data */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore inqdata[4] = 31;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Vendor Identification */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bcopy("Areca ", &inqdata[8], VIDLEN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Product Identification */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bcopy("RAID controller ", &inqdata[16],
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore PIDLEN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Product Revision */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bcopy(&inqdata[32], "R001", REVLEN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (bp->b_flags & (B_PHYS | B_PAGEIO))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bp_mapin(bp);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memcpy(bp->b_un.b_addr,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore inqdata, sizeof (inqdata));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_state |= STATE_XFERRED_DATA;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccb_complete(ccb, 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRAN_ACCEPT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCMD_WRITE_BUFFER:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCMD_READ_BUFFER: {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_iop_message_xfer(acb, pkt)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* error just for retry */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_TRAN_ERR;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_statistics |= STAT_TERMINATED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_state |= STATE_XFERRED_DATA;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccb_complete(ccb, 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRAN_ACCEPT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_state |= STATE_XFERRED_DATA;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccb_complete(ccb, 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRAN_ACCEPT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->devstate[target][lun] == ARECA_RAID_GONE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t block_cmd;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore block_cmd = pkt->pkt_cdbp[0] & 0x0f;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (block_cmd == 0x08 || block_cmd == 0x0a) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_reason = CMD_TIMEOUT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_statistics |= STAT_TIMEOUT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore STATE_SENT_CMD | STATE_GOT_STATUS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((ccb->ccb_flags & CCB_FLAG_DMACONSISTENT) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (pkt->pkt_state & STATE_XFERRED_DATA)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_sync(ccb->pkt_dma_handle,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dma_offset,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dma_len, DDI_DMA_SYNC_FORCPU);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_pkt_comp(pkt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRAN_ACCEPT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->postq_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->ccboutstandingcount >= ARCMSR_MAX_OUTSTANDING_CMD) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state = ARCMSR_CCB_RETRY;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->postq_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRAN_BUSY);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else if (arcmsr_post_ccb(acb, ccb) == DDI_FAILURE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "post ccb failure, ccboutstandingcount = %d",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->ccboutstandingcount);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->postq_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRAN_FATAL_ERROR);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->postq_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRAN_ACCEPT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function name: arcmsr_tran_destroy_pkt
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return Values: none
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Description: Called by kernel on behalf of a target driver
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * calling scsi_destroy_pkt(9F).
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Refer to tran_destroy_pkt(9E) man page
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Context: Can be called from different kernel process threads.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Can be called by interrupt thread.
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb = pkt->pkt_ha_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_handle_t pkt_dma_handle = ccb->pkt_dma_handle;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->pkt != pkt) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_flags & CCB_FLAG_DMAVALID) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_flags &= ~CCB_FLAG_DMAVALID;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (pkt_dma_handle) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_unbind_handle(ccb->pkt_dma_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (pkt_dma_handle) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_free_handle(&pkt_dma_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_ha_private = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state & ARCMSR_ABNORMAL_MASK) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state & ARCMSR_CCB_BACK) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_free_ccb(ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state |= ARCMSR_CCB_WAIT4_FREE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_free_ccb(ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_pkt_free(ap, pkt);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function name: arcmsr_tran_dmafree()
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return Values: none
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Description: free dvma resources
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Context: Can be called from different kernel process threads.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Can be called by interrupt thread.
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb = pkt->pkt_ha_private;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((ccb == NULL) || (ccb->pkt != pkt)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_flags & CCB_FLAG_DMAVALID) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_flags &= ~CCB_FLAG_DMAVALID;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_unbind_handle(ccb->pkt_dma_handle) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(ccb->acb, "ddi_dma_unbind_handle() failed "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "(target %d lun %d)", ap->a_target, ap->a_lun);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&ccb->pkt_dma_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dma_handle = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function name: arcmsr_tran_sync_pkt()
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return Values: none
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Description: sync dma
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Context: Can be called from different kernel process threads.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Can be called by interrupt thread.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = pkt->pkt_ha_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((ccb == NULL) || (ccb->pkt != pkt)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_flags & CCB_FLAG_DMAVALID) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_sync(ccb->pkt_dma_handle, 0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (ccb->ccb_flags & CCB_FLAG_DMAWRITE) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU) !=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(ccb->acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "sync pkt failed for target %d lun %d",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ap->a_target, ap->a_lun);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_tran_abort(9E)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * SCSA interface routine to abort pkt(s) in progress.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Aborts the pkt specified. If NULL pkt, aborts ALL pkts.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Output: Return 1 if success
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return 0 if failure
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_tran_abort(struct scsi_address *ap, struct scsi_pkt *abortpkt)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int return_code;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb = ap->a_hba_tran->tran_hba_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while (acb->ccboutstandingcount != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore drv_usecwait(10000);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return_code = arcmsr_seek_cmd2abort(acb, abortpkt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->isr_mutex);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (return_code != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "abort command failed for target %d lun %d",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ap->a_target, ap->a_lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (0);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_tran_reset(9E)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * SCSA interface routine to perform scsi resets on either
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * a specified target or the bus (default).
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Output: Return 1 if success
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return 0 if failure
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_tran_reset(struct scsi_address *ap, int level) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int return_code = 1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int target = ap->a_target;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int lun = ap->a_lun;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Are we in the middle of dumping core? */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_in_panic())
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (return_code);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb = (struct ACB *)ap->a_hba_tran->tran_hba_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (level) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case RESET_ALL: /* 0 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->num_resets++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags |= ACB_F_BUS_RESET;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->timeout_count) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_iop_reset(acb) != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_handle_iop_bus_hold(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_BUS_HANG_ON;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_BUS_RESET;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case RESET_TARGET: /* 1 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->devstate[target][lun] == ARECA_RAID_GONE)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return_code = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case RESET_BUS: /* 2 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return_code = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case RESET_LUN: /* 3 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return_code = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return_code = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (return_code);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_tran_bus_config(dev_info_t *parent, uint_t flags,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct ACB *acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int circ = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int rval;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int tgt, lun;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((acb = ddi_get_soft_state(arcmsr_soft_state,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_get_instance(parent))) == NULL)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (NDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ndi_devi_enter(parent, &circ);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (op) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case BUS_CONFIG_ONE:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_parse_devname(arg, &tgt, &lun) != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = NDI_FAILURE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->device_map[tgt] & 1 << lun) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->devstate[tgt][lun] = ARECA_RAID_GOOD;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = arcmsr_config_lun(acb, tgt, lun, childp);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case BUS_CONFIG_DRIVER:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case BUS_CONFIG_ALL:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (tgt = 0; tgt < ARCMSR_MAX_TARGETID; tgt++)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->device_map[tgt] & 1 << lun) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->devstate[tgt][lun] =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARECA_RAID_GOOD;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) arcmsr_config_lun(acb, tgt,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore lun, NULL);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = NDI_SUCCESS;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (rval == NDI_SUCCESS)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = ndi_busop_bus_config(parent, flags, op, arg, childp, 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ndi_devi_exit(parent, circ);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (rval);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Function name: arcmsr_dma_alloc
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Return Values: 0 if successful, -1 if failure
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Description: allocate DMA resources
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Context: Can only be called from arcmsr_tran_init_pkt()
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * register struct scsi_address *ap = &((pkt)->pkt_address);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonarcmsr_dma_alloc(struct ACB *acb, struct scsi_pkt *pkt,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct buf *bp, int flags, int (*callback)())
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct CCB *ccb = pkt->pkt_ha_private;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int alloc_result, map_method, dma_flags;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int resid = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int total_ccb_xferlen = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int (*cb)(caddr_t);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson uint8_t i;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * at this point the PKT SCSI CDB is empty, and dma xfer length
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * is bp->b_bcount
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (bp->b_flags & B_READ) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->ccb_flags &= ~CCB_FLAG_DMAWRITE;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson dma_flags = DDI_DMA_READ;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } else {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->ccb_flags |= CCB_FLAG_DMAWRITE;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson dma_flags = DDI_DMA_WRITE;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (flags & PKT_CONSISTENT) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->ccb_flags |= CCB_FLAG_DMACONSISTENT;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson dma_flags |= DDI_DMA_CONSISTENT;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (flags & PKT_DMA_PARTIAL) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson dma_flags |= DDI_DMA_PARTIAL;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson dma_flags |= DDI_DMA_REDZONE;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore alloc_result = ddi_dma_alloc_handle(acb->dev_info, &arcmsr_dma_attr,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cb, 0, &ccb->pkt_dma_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (alloc_result != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "dma allocate failed (%x)", alloc_result);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore map_method = ddi_dma_buf_bind_handle(ccb->pkt_dma_handle,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bp, dma_flags, cb, 0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &ccb->pkt_dmacookies[0], /* SG List pointer */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &ccb->pkt_ncookies); /* number of sgl cookies */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson switch (map_method) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case DDI_DMA_PARTIAL_MAP:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * When your main memory size larger then 4G
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * DDI_DMA_PARTIAL_MAP will be touched.
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson *
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * We've already set DDI_DMA_PARTIAL in dma_flags,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * so if it's now missing, there's something screwy
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * happening. We plow on....
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if ((dma_flags & DDI_DMA_PARTIAL) == 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "dma partial mapping lost ...impossible case!");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (ddi_dma_numwin(ccb->pkt_dma_handle, &ccb->pkt_nwin) ==
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DDI_FAILURE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_numwin() failed");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (ddi_dma_getwin(ccb->pkt_dma_handle, ccb->pkt_curwin,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &ccb->pkt_dma_offset, &ccb->pkt_dma_len,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &ccb->pkt_dmacookies[0], &ccb->pkt_ncookies) ==
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DDI_FAILURE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_getwin failed");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson i = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* first cookie is accessed from ccb->pkt_dmacookies[0] */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson total_ccb_xferlen = ccb->pkt_dmacookies[0].dmac_size;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson for (;;) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson i++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((i == ARCMSR_MAX_SG_ENTRIES) ||
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (i == ccb->pkt_ncookies) ||
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (total_ccb_xferlen == ARCMSR_MAX_XFER_LEN)) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * next cookie will be retrieved from
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * ccb->pkt_dmacookies[i]
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ddi_dma_nextcookie(ccb->pkt_dma_handle,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &ccb->pkt_dmacookies[i]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson total_ccb_xferlen += ccb->pkt_dmacookies[i].dmac_size;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_cookie = i;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->arcmsr_cdb.sgcount = i;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (total_ccb_xferlen > 512) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson resid = total_ccb_xferlen % 512;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (resid != 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson i--;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson total_ccb_xferlen -= resid;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* modify last sg length */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dmacookies[i].dmac_size =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dmacookies[i].dmac_size - resid;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->resid_dmacookie.dmac_size = resid;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->resid_dmacookie.dmac_laddress =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dmacookies[i].dmac_laddress +
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dmacookies[i].dmac_size;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->total_dmac_size = total_ccb_xferlen;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->ccb_flags |= CCB_FLAG_DMAVALID;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson pkt->pkt_resid = bp->b_bcount - ccb->total_dmac_size;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (DDI_SUCCESS);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case DDI_DMA_MAPPED:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_nwin = 1; /* all mapped, so only one window */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dma_len = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dma_offset = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson i = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* first cookie is accessed from ccb->pkt_dmacookies[0] */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson total_ccb_xferlen = ccb->pkt_dmacookies[0].dmac_size;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson for (;;) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson i++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((i == ARCMSR_MAX_SG_ENTRIES) ||
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (i == ccb->pkt_ncookies) ||
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (total_ccb_xferlen == ARCMSR_MAX_XFER_LEN)) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * next cookie will be retrieved from
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * ccb->pkt_dmacookies[i]
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ddi_dma_nextcookie(ccb->pkt_dma_handle,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &ccb->pkt_dmacookies[i]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson total_ccb_xferlen += ccb->pkt_dmacookies[i].dmac_size;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_cookie = i;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->arcmsr_cdb.sgcount = i;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (total_ccb_xferlen > 512) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson resid = total_ccb_xferlen % 512;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (resid != 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson i--;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson total_ccb_xferlen -= resid;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* modify last sg length */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dmacookies[i].dmac_size =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dmacookies[i].dmac_size - resid;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->resid_dmacookie.dmac_size = resid;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->resid_dmacookie.dmac_laddress =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dmacookies[i].dmac_laddress +
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dmacookies[i].dmac_size;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->total_dmac_size = total_ccb_xferlen;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->ccb_flags |= CCB_FLAG_DMAVALID;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson pkt->pkt_resid = bp->b_bcount - ccb->total_dmac_size;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (DDI_SUCCESS);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case DDI_DMA_NORESOURCES:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "dma map got 'no resources'");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson bioerror(bp, ENOMEM);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case DDI_DMA_NOMAPPING:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "dma map got 'no mapping'");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson bioerror(bp, EFAULT);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case DDI_DMA_TOOBIG:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "dma map got 'too big'");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson bioerror(bp, EINVAL);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case DDI_DMA_INUSE:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "dma map got 'in use' "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "(should not happen)");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "dma map failed (0x%x)", i);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ddi_dma_free_handle(&ccb->pkt_dma_handle);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dma_handle = NULL;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->ccb_flags &= ~CCB_FLAG_DMAVALID;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Function name: arcmsr_dma_move
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Return Values: 0 if successful, -1 if failure
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Description: move DMA resources to next DMA window
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Context: Can only be called from arcmsr_tran_init_pkt()
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_dma_move(struct ACB *acb, struct scsi_pkt *pkt, struct buf *bp)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct CCB *ccb = pkt->pkt_ha_private;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson uint8_t i = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int resid = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int total_ccb_xferlen = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (ccb->resid_dmacookie.dmac_size != 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson total_ccb_xferlen += ccb->resid_dmacookie.dmac_size;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dmacookies[i].dmac_size =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->resid_dmacookie.dmac_size;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_dmacookies[i].dmac_laddress =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->resid_dmacookie.dmac_laddress;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson i++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->resid_dmacookie.dmac_size = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * If there are no more cookies remaining in this window,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * move to the next window.
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (ccb->pkt_cookie == ccb->pkt_ncookies) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * only dma map "partial" arrive here
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if ((ccb->pkt_curwin == ccb->pkt_nwin) &&
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (ccb->pkt_nwin == 1)) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (DDI_SUCCESS);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* At last window, cannot move */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (++ccb->pkt_curwin >= ccb->pkt_nwin) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "dma partial set, numwin exceeded");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (ddi_dma_getwin(ccb->pkt_dma_handle, ccb->pkt_curwin,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &ccb->pkt_dma_offset, &ccb->pkt_dma_len,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &ccb->pkt_dmacookies[i], &ccb->pkt_ncookies) ==
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DDI_FAILURE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_getwin failed");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* reset cookie pointer */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt_cookie = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } else {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * only dma map "all" arrive here
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * We still have more cookies in this window,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * get the next one
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * access the pkt_dma_handle remain cookie record at
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * ccb->pkt_dmacookies array
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ddi_dma_nextcookie(ccb->pkt_dma_handle,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &ccb->pkt_dmacookies[i]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Get remaining cookies in this window, up to our maximum */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore total_ccb_xferlen += ccb->pkt_dmacookies[i].dmac_size;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* retrieve and store cookies, start at ccb->pkt_dmacookies[0] */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (;;) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore i++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* handled cookies count level indicator */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_cookie++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((i == ARCMSR_MAX_SG_ENTRIES) ||
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (ccb->pkt_cookie == ccb->pkt_ncookies) ||
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (total_ccb_xferlen == ARCMSR_MAX_XFER_LEN)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_nextcookie(ccb->pkt_dma_handle,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &ccb->pkt_dmacookies[i]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore total_ccb_xferlen += ccb->pkt_dmacookies[i].dmac_size;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->arcmsr_cdb.sgcount = i;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (total_ccb_xferlen > 512) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore resid = total_ccb_xferlen % 512;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (resid != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore i--;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore total_ccb_xferlen -= resid;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* modify last sg length */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dmacookies[i].dmac_size =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dmacookies[i].dmac_size - resid;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->resid_dmacookie.dmac_size = resid;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->resid_dmacookie.dmac_laddress =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dmacookies[i].dmac_laddress +
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dmacookies[i].dmac_size;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->total_dmac_size += total_ccb_xferlen;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_resid = bp->b_bcount - ccb->total_dmac_size;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*ARGSUSED*/
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_build_ccb(struct CCB *ccb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_pkt *pkt = ccb->pkt;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ARCMSR_CDB *arcmsr_cdb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *psge;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t address_lo, address_hi;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int arccdbsize = 0x30;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t sgcount;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore psge = (char *)&arcmsr_cdb->sgu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bcopy((caddr_t)pkt->pkt_cdbp, arcmsr_cdb->Cdb, arcmsr_cdb->CdbLength);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sgcount = ccb->arcmsr_cdb.sgcount;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (sgcount != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int length, i;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int cdb_sgcount = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int total_xfer_length = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* map stor port SG list to our iop SG List. */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < sgcount; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Get physaddr of the current data pointer */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore length = ccb->pkt_dmacookies[i].dmac_size;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore total_xfer_length += length;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore address_lo =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_addr_lo32(ccb->pkt_dmacookies[i].dmac_laddress);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore address_hi =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_addr_hi32(ccb->pkt_dmacookies[i].dmac_laddress);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (address_hi == 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct SG32ENTRY *dma_sg;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_sg = (struct SG32ENTRY *)(intptr_t)psge;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_sg->address = address_lo;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_sg->length = length;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore psge += sizeof (struct SG32ENTRY);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arccdbsize += sizeof (struct SG32ENTRY);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct SG64ENTRY *dma_sg;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_sg = (struct SG64ENTRY *)(intptr_t)psge;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_sg->addresshigh = address_hi;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_sg->address = address_lo;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_sg->length = length | IS_SG64_ADDR;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore psge += sizeof (struct SG64ENTRY);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arccdbsize += sizeof (struct SG64ENTRY);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sgcount++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->sgcount = (uint8_t)cdb_sgcount;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->DataLength = total_xfer_length;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arccdbsize > 256) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->DataLength = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_flags & CCB_FLAG_DMAWRITE)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->arc_cdb_size = arccdbsize;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * arcmsr_post_ccb - Send a protocol specific ARC send postcard to a AIOC.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * handle: Handle of registered ARC protocol driver
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * adapter_id: AIOC unique identifier(integer)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * pPOSTCARD_SEND: Pointer to ARC send postcard
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * This routine posts a ARC send postcard to the request post FIFO of a
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * specific ARC adapter.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_post_ccb(struct ACB *acb, struct CCB *ccb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t cdb_phyaddr_pattern = ccb->cdb_phyaddr_pattern;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_pkt *pkt = ccb->pkt;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ARCMSR_CDB *arcmsr_cdb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint_t pkt_flags = pkt->pkt_flags;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_cdb = &ccb->arcmsr_cdb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* TODO: Use correct offset and size for syncing? */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_sync(acb->ccbs_pool_handle, 0, 0, DDI_DMA_SYNC_FORDEV) ==
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_FAILURE)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_32(&acb->ccboutstandingcount);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_time = (time_t)(ddi_get_time() + pkt->pkt_time);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state = ARCMSR_CCB_START;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->inbound_queueport,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_phyaddr_pattern |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_CCBPOST_FLAG_SGL_BSIZE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->inbound_queueport, cdb_phyaddr_pattern);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (pkt_flags & FLAG_NOINTR)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_polling_hba_ccbdone(acb, ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int ending_index, index;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore index = phbbmu->postq_index;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ending_index = ((index+1)%ARCMSR_MAX_HBB_POSTQUEUE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->post_qbuffer[ending_index] = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->post_qbuffer[index] =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (cdb_phyaddr_pattern|ARCMSR_CCBPOST_FLAG_SGL_BSIZE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->post_qbuffer[index] = cdb_phyaddr_pattern;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore index++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* if last index number set it to 0 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore index %= ARCMSR_MAX_HBB_POSTQUEUE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->postq_index = index;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DRV2IOP_CDB_POSTED);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (pkt_flags & FLAG_NOINTR)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_polling_hbb_ccbdone(acb, ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t ccb_post_stamp, arc_cdb_size;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arc_cdb_size = (ccb->arc_cdb_size > 0x300) ? 0x300 :
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->arc_cdb_size;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_post_stamp = (cdb_phyaddr_pattern |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ((arc_cdb_size-1) >> 6) |1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->cdb_phyaddr_hi32) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_queueport_high,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->cdb_phyaddr_hi32);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_queueport_low, ccb_post_stamp);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_queueport_low, ccb_post_stamp);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (pkt_flags & FLAG_NOINTR)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_polling_hbc_ccbdone(acb, ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_ccb_complete(struct CCB *ccb, int flag)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb = ccb->acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_pkt *pkt = ccb->pkt;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (pkt == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state |= ARCMSR_CCB_DONE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore STATE_SENT_CMD | STATE_GOT_STATUS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((ccb->ccb_flags & CCB_FLAG_DMACONSISTENT) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (pkt->pkt_state & STATE_XFERRED_DATA)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_sync(ccb->pkt_dma_handle, 0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SYNC_FORCPU);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * TODO: This represents a potential race condition, and is
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * ultimately a poor design decision. Revisit this code
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * and solve the mutex ownership issue correctly.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (mutex_owned(&acb->isr_mutex)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_pkt_comp(pkt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_pkt_comp(pkt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (flag == 1) {
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&acb->ccboutstandingcount);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_report_ccb_state(struct ACB *acb, struct CCB *ccb, boolean_t error)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int id, lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state |= ARCMSR_CCB_DONE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore id = ccb->pkt->pkt_address.a_target;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore lun = ccb->pkt->pkt_address.a_lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!error) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->devstate[id][lun] == ARECA_RAID_GONE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->devstate[id][lun] = ARECA_RAID_GOOD;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_CMPLT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_state |= STATE_XFERRED_DATA;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_list_add_tail(&acb->ccb_complete_list_mutex,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &ccb->complete_queue_pointer, &acb->ccb_complete_list);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (ccb->arcmsr_cdb.DeviceStatus) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_DEV_SELECT_TIMEOUT:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->devstate[id][lun] == ARECA_RAID_GOOD) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "target %d lun %d selection "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout", id, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->devstate[id][lun] = ARECA_RAID_GONE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_TIMEOUT; /* CMD_DEV_GONE; */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_statistics |= STAT_TIMEOUT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_list_add_tail(&acb->ccb_complete_list_mutex,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &ccb->complete_queue_pointer,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->ccb_complete_list);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_DEV_ABORTED:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_DEV_INIT_FAIL:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "isr got 'ARCMSR_DEV_ABORTED'"
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore " 'ARCMSR_DEV_INIT_FAIL'");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_NOTE, "raid volume was kicked out");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->devstate[id][lun] = ARECA_RAID_GONE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_DEV_GONE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_statistics |= STAT_TERMINATED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_list_add_tail(&acb->ccb_complete_list_mutex,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &ccb->complete_queue_pointer,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->ccb_complete_list);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case SCSISTAT_CHECK_CONDITION:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->devstate[id][lun] = ARECA_RAID_GOOD;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_report_sense_info(ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_list_add_tail(&acb->ccb_complete_list_mutex,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &ccb->complete_queue_pointer,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->ccb_complete_list);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "target %d lun %d isr received CMD_DONE"
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore " with unknown DeviceStatus (0x%x)",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore id, lun, ccb->arcmsr_cdb.DeviceStatus);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_NOTE, "raid volume was kicked out");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->devstate[id][lun] = ARECA_RAID_GONE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* unknown error or crc error just for retry */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_TRAN_ERR;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_statistics |= STAT_TERMINATED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_list_add_tail(&acb->ccb_complete_list_mutex,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &ccb->complete_queue_pointer,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->ccb_complete_list);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_drain_donequeue(struct ACB *acb, struct CCB *ccb, boolean_t error)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint16_t ccb_state;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->acb != acb) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state != ARCMSR_CCB_START) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (ccb->ccb_state & ARCMSR_ABNORMAL_MASK) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_CCB_TIMEOUT:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_state = ccb->ccb_state;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb_state & ARCMSR_CCB_WAIT4_FREE)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_free_ccb(ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore else
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state |= ARCMSR_CCB_BACK;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_CCB_ABORTED:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_state = ccb->ccb_state;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb_state & ARCMSR_CCB_WAIT4_FREE)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_free_ccb(ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore else
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state |= ARCMSR_CCB_BACK;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ARCMSR_CCB_RESET:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_state = ccb->ccb_state;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb_state & ARCMSR_CCB_WAIT4_FREE)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_free_ccb(ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore else
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state |= ARCMSR_CCB_BACK;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_report_ccb_state(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_report_sense_info(struct CCB *ccb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct SENSE_DATA *cdb_sensedata;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_pkt *pkt = ccb->pkt;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_arq_status *arq_status;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore union scsi_cdb *cdbp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint64_t err_blkno;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdbp = (void *)pkt->pkt_cdbp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore err_blkno = ARCMSR_GETGXADDR(ccb->arcmsr_cdb.CdbLength, cdbp);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status = (struct scsi_arq_status *)(intptr_t)(pkt->pkt_scbp);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero((caddr_t)arq_status, sizeof (struct scsi_arq_status));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *pkt->pkt_scbp = STATUS_CHECK; /* CHECK CONDITION */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_reason = CMD_CMPLT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_state = (STATE_GOT_BUS | STATE_GOT_TARGET |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore STATE_SENT_CMD | STATE_XFERRED_DATA | STATE_GOT_STATUS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_statistics = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_resid = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_reason = CMD_CMPLT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* auto rqsense took place */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_state |= STATE_ARQ_DONE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sensedata = (struct SENSE_DATA *)ccb->arcmsr_cdb.SenseData;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (&arq_status->sts_sensedata != NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (err_blkno <= 0xfffffffful) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_extended_sense *sts_sensedata;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata = &arq_status->sts_sensedata;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_code = cdb_sensedata->ErrorCode;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* must eq CLASS_EXTENDED_SENSE (0x07) */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_class = cdb_sensedata->ErrorClass;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_valid = cdb_sensedata->Valid;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_segnum = cdb_sensedata->SegmentNumber;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_key = cdb_sensedata->SenseKey;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_ili = cdb_sensedata->IncorrectLength;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_eom = cdb_sensedata->EndOfMedia;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_filmk = cdb_sensedata->FileMark;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_info_1 = (err_blkno >> 24) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_info_2 = (err_blkno >> 16) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_info_3 = (err_blkno >> 8) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_info_4 = err_blkno & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_add_len =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sensedata->AdditionalSenseLength;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_cmd_info[0] =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sensedata->CommandSpecificInformation[0];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_cmd_info[1] =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sensedata->CommandSpecificInformation[1];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_cmd_info[2] =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sensedata->CommandSpecificInformation[2];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_cmd_info[3] =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sensedata->CommandSpecificInformation[3];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_add_code =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sensedata->AdditionalSenseCode;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_qual_code =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sensedata->AdditionalSenseCodeQualifier;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_fru_code =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sensedata->FieldReplaceableUnitCode;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else { /* 64-bit LBA */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_descr_sense_hdr *dsp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_information_sense_descr *isd;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dsp = (struct scsi_descr_sense_hdr *)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &arq_status->sts_sensedata;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dsp->ds_class = CLASS_EXTENDED_SENSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dsp->ds_code = CODE_FMT_DESCR_CURRENT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dsp->ds_key = cdb_sensedata->SenseKey;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dsp->ds_add_code = cdb_sensedata->AdditionalSenseCode;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dsp->ds_qual_code =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_sensedata->AdditionalSenseCodeQualifier;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dsp->ds_addl_sense_length =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct scsi_information_sense_descr);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd = (struct scsi_information_sense_descr *)(dsp+1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd->isd_descr_type = DESCR_INFORMATION;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd->isd_valid = 1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd->isd_information[0] = (err_blkno >> 56) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd->isd_information[1] = (err_blkno >> 48) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd->isd_information[2] = (err_blkno >> 40) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd->isd_information[3] = (err_blkno >> 32) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd->isd_information[4] = (err_blkno >> 24) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd->isd_information[5] = (err_blkno >> 16) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd->isd_information[6] = (err_blkno >> 8) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isd->isd_information[7] = (err_blkno) & 0xFF;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_seek_cmd2abort(struct ACB *acb, struct scsi_pkt *abortpkt)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t intmask_org = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int i = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->num_aborts++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (abortpkt != NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * We don't support abort of a single packet. All
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * callers in our kernel always do a global abort, so
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * there is no point in having code to support it
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * here.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * if abortpkt is NULL, the upper layer needs us
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * to abort all commands
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->ccboutstandingcount != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* disable all outbound interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = arcmsr_disable_allintr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear and abort all outbound posted Q */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_done4abort_postqueue(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* talk to iop 331 outstanding command aborted */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) arcmsr_abort_host_command(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = acb->pccb_pool[i];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state == ARCMSR_CCB_START) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * this ccb will complete at
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * hwinterrupt
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* ccb->ccb_state = ARCMSR_CCB_ABORTED; */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_ABORTED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_statistics |= STAT_ABORTED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccb_complete(ccb, 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * enable outbound Post Queue, outbound
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * doorbell Interrupt
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Autoconfiguration support
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_parse_devname(char *devnm, int *tgt, int *lun) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char devbuf[SCSI_MAXNAMELEN];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *addr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *p, *tp, *lp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore long num;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Parse dev name and address */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) strlcpy(devbuf, devnm, sizeof (devbuf));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore addr = "";
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (p = devbuf; *p != '\0'; p++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (*p == '@') {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore addr = p + 1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *p = '\0';
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else if (*p == ':') {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *p = '\0';
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Parse target and lun */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (p = tp = addr, lp = NULL; *p != '\0'; p++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (*p == ',') {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore lp = p + 1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *p = '\0';
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((tgt != NULL) && (tp != NULL)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_strtol(tp, NULL, 0x10, &num) != 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (-1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *tgt = (int)num;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((lun != NULL) && (lp != NULL)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_strtol(lp, NULL, 0x10, &num) != 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (-1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *lun = (int)num;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_name_node(dev_info_t *dip, char *name, int len)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int tgt, lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore tgt = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "target",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore -1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (tgt == -1)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore lun = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "lun",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore -1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (lun == -1)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) snprintf(name, len, "%x,%x", tgt, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic dev_info_t *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_find_child(struct ACB *acb, uint16_t tgt, uint8_t lun)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_info_t *child = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char addr[SCSI_MAXNAMELEN];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char tmp[SCSI_MAXNAMELEN];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) sprintf(addr, "%x,%x", tgt, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (child = ddi_get_child(acb->dev_info);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore child;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore child = ddi_get_next_sibling(child)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* We don't care about non-persistent node */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ndi_dev_is_persistent_node(child) == 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_name_node(child, tmp, SCSI_MAXNAMELEN) !=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_SUCCESS)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (strcmp(addr, tmp) == 0)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (child);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_config_child(struct ACB *acb, struct scsi_device *sd, dev_info_t **dipp)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *nodename = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char **compatible = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int ncompatible = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_info_t *ldip = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int tgt = sd->sd_address.a_target;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int lun = sd->sd_address.a_lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int dtype = sd->sd_inq->inq_dtype & DTYPE_MASK;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int rval;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_nodename_compatible_get(sd->sd_inq, NULL, dtype,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore NULL, &nodename, &compatible, &ncompatible);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (nodename == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "found no comptible driver for T%dL%d",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore tgt, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = NDI_FAILURE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto finish;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Create dev node */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = ndi_devi_alloc(acb->dev_info, nodename, DEVI_SID_NODEID, &ldip);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (rval == NDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ndi_prop_update_int(DDI_DEV_T_NONE, ldip, "target", tgt) !=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_PROP_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "unable to create target property for T%dL%d",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore tgt, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = NDI_FAILURE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto finish;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ndi_prop_update_int(DDI_DEV_T_NONE, ldip, "lun", lun) !=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_PROP_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "unable to create lun property for T%dL%d",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore tgt, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = NDI_FAILURE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto finish;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ndi_prop_update_string_array(DDI_DEV_T_NONE, ldip,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "compatible", compatible, ncompatible) !=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_PROP_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "unable to create compatible property for T%dL%d",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore tgt, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = NDI_FAILURE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto finish;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = ndi_devi_online(ldip, NDI_ONLINE_ATTACH);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (rval != NDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "unable to online T%dL%d", tgt, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ndi_prop_remove_all(ldip);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ndi_devi_free(ldip);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_NOTE, "T%dL%d onlined", tgt, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorefinish:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (dipp)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *dipp = ldip;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_nodename_compatible_free(nodename, compatible);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (rval);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_config_lun(struct ACB *acb, uint16_t tgt, uint8_t lun, dev_info_t **ldip)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_device sd;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_info_t *child;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int rval;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((child = arcmsr_find_child(acb, tgt, lun)) != NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ldip) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *ldip = child;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (NDI_SUCCESS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero(&sd, sizeof (struct scsi_device));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sd.sd_address.a_hba_tran = acb->scsi_hba_transport;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sd.sd_address.a_target = tgt;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sd.sd_address.a_lun = lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = scsi_hba_probe(&sd, NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (rval == SCSIPROBE_EXISTS)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = arcmsr_config_child(acb, &sd, ldip);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_unprobe(&sd);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (rval);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_add_intr(struct ACB *acb, int intr_type)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int rc, count;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_info_t *dev_info;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore const char *type_str;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (intr_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case DDI_INTR_TYPE_MSI:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type_str = "MSI";
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case DDI_INTR_TYPE_MSIX:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type_str = "MSIX";
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case DDI_INTR_TYPE_FIXED:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type_str = "FIXED";
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type_str = "unknown";
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_info = acb->dev_info;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Determine number of supported interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rc = ddi_intr_get_nintrs(dev_info, intr_type, &count);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((rc != DDI_SUCCESS) || (count == 0)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "no interrupts of type %s, rc=0x%x, count=%d",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type_str, rc, count);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->intr_size = sizeof (ddi_intr_handle_t) * count;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->phandle = kmem_zalloc(acb->intr_size, KM_SLEEP);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rc = ddi_intr_alloc(dev_info, acb->phandle, intr_type, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore count, &acb->intr_count, DDI_INTR_ALLOC_NORMAL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((rc != DDI_SUCCESS) || (acb->intr_count == 0)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_intr_alloc(%s) failed 0x%x",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type_str, rc);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->intr_count < count) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_NOTE, "Got %d interrupts, but requested %d",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->intr_count, count);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Get priority for first msi, assume remaining are all the same
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_intr_get_pri(acb->phandle[0], &acb->intr_pri) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_intr_get_pri failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->intr_pri >= ddi_intr_get_hilevel_pri()) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "high level interrupt not supported");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (int x = 0; x < acb->intr_count; x++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_intr_add_handler(acb->phandle[x], arcmsr_intr_handler,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (caddr_t)acb, NULL) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_intr_add_handler(%s) failed",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type_str);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_intr_get_cap(acb->phandle[0], &acb->intr_cap);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->intr_cap & DDI_INTR_FLAG_BLOCK) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Call ddi_intr_block_enable() for MSI */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_intr_block_enable(acb->phandle, acb->intr_count);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Call ddi_intr_enable() for MSI non block enable */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (int x = 0; x < acb->intr_count; x++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_intr_enable(acb->phandle[x]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_SUCCESS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_remove_intr(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int x;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->phandle == NULL)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Disable all interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->intr_cap & DDI_INTR_FLAG_BLOCK) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Call ddi_intr_block_disable() */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_intr_block_disable(acb->phandle, acb->intr_count);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (x = 0; x < acb->intr_count; x++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_intr_disable(acb->phandle[x]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Call ddi_intr_remove_handler() */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (x = 0; x < acb->intr_count; x++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_intr_remove_handler(acb->phandle[x]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_intr_free(acb->phandle[x]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore kmem_free(acb->phandle, acb->intr_size);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->phandle = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_mutex_init(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_init(&acb->isr_mutex, NULL, MUTEX_DRIVER, NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_init(&acb->acb_mutex, NULL, MUTEX_DRIVER, NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_init(&acb->postq_mutex, NULL, MUTEX_DRIVER, NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_init(&acb->workingQ_mutex, NULL, MUTEX_DRIVER, NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_init(&acb->ioctl_mutex, NULL, MUTEX_DRIVER, NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_mutex_destroy(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_destroy(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_destroy(&acb->acb_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_destroy(&acb->postq_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_destroy(&acb->workingQ_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_destroy(&acb->ioctl_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_initialize(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *pccb_tmp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore size_t allocated_length;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint16_t wval;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint_t intmask_org, count;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore caddr_t arcmsr_ccbs_area;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t wlval, cdb_phyaddr, offset, realccb_size;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int32_t dma_sync_size;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int i, id, lun, instance;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore instance = ddi_get_instance(acb->dev_info);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore wlval = pci_config_get32(acb->pci_acc_handle, 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore wval = (uint16_t)((wlval >> 16) & 0xffff);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore realccb_size = P2ROUNDUP(sizeof (struct CCB), 32);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (wval) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1880:
7d14b8f218dc86a431d15e352b4bf15fbb1b3596Robert Mustacchi case PCI_DEVICE_ID_ARECA_1882:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t *iop_mu_regs_map0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->adapter_type = ACB_ADAPTER_TYPE_C; /* lsi */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_sync_size = ARCMSR_MAX_FREECCB_NUM * realccb_size + 0x20;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_regs_map_setup(acb->dev_info, 2,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (caddr_t *)&iop_mu_regs_map0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct HBC_msgUnit), &acb->dev_acc_attr,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->reg_mu_acc_handle0) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "unable to map registers");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((i = ddi_dma_alloc_handle(acb->dev_info, &arcmsr_ccb_attr,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SLEEP, NULL, &acb->ccbs_pool_handle)) !=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_regs_map_free(&acb->reg_mu_acc_handle0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_alloc_handle failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_mem_alloc(acb->ccbs_pool_handle, dma_sync_size,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->dev_acc_attr, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SLEEP, NULL, (caddr_t *)&arcmsr_ccbs_area,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &allocated_length, &acb->ccbs_acc_handle) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_mem_alloc failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_regs_map_free(&acb->reg_mu_acc_handle0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_addr_bind_handle(acb->ccbs_pool_handle, NULL,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (caddr_t)arcmsr_ccbs_area, dma_sync_size, DDI_DMA_RDWR |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &acb->ccb_cookie,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &count) != DDI_DMA_MAPPED) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_addr_bind_handle failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_mem_free(&acb->ccbs_acc_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_regs_map_free(&acb->reg_mu_acc_handle0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero(arcmsr_ccbs_area, dma_sync_size);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore offset = (uint32_t)(P2ROUNDUP(PtrToNum(arcmsr_ccbs_area), 32)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore - PtrToNum(arcmsr_ccbs_area));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccbs_area = arcmsr_ccbs_area + offset;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* ioport base */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->pmu = (struct msgUnit *)(intptr_t)iop_mu_regs_map0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1201:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t *iop_mu_regs_map0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t *iop_mu_regs_map1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->adapter_type = ACB_ADAPTER_TYPE_B; /* marvell */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_sync_size =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (ARCMSR_MAX_FREECCB_NUM * realccb_size + 0x20) +
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct HBB_msgUnit);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Allocate memory for the ccb */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((i = ddi_dma_alloc_handle(acb->dev_info, &arcmsr_ccb_attr,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SLEEP, NULL, &acb->ccbs_pool_handle)) !=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_alloc_handle failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_mem_alloc(acb->ccbs_pool_handle, dma_sync_size,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->dev_acc_attr, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SLEEP, NULL, (caddr_t *)&arcmsr_ccbs_area,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &allocated_length, &acb->ccbs_acc_handle) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_mem_alloc failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_addr_bind_handle(acb->ccbs_pool_handle, NULL,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (caddr_t)arcmsr_ccbs_area, dma_sync_size,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore NULL, &acb->ccb_cookie, &count) != DDI_DMA_MAPPED) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_addr_bind_handle failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_mem_free(&acb->ccbs_acc_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero(arcmsr_ccbs_area, dma_sync_size);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore offset = (uint32_t)(P2ROUNDUP(PtrToNum(arcmsr_ccbs_area), 32)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore - PtrToNum(arcmsr_ccbs_area));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccbs_area = arcmsr_ccbs_area + offset;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->pmu = (struct msgUnit *)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore NumToPtr(PtrToNum(arcmsr_ccbs_area) +
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (realccb_size*ARCMSR_MAX_FREECCB_NUM));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* setup device register */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_regs_map_setup(acb->dev_info, 1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (caddr_t *)&iop_mu_regs_map0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct HBB_DOORBELL), &acb->dev_acc_attr,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->reg_mu_acc_handle0) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "unable to map base0 registers");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_unbind_handle(acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_mem_free(&acb->ccbs_acc_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* ARCMSR_DRV2IOP_DOORBELL */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)iop_mu_regs_map0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_regs_map_setup(acb->dev_info, 2,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (caddr_t *)&iop_mu_regs_map1, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct HBB_RWBUFFER), &acb->dev_acc_attr,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->reg_mu_acc_handle1) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "unable to map base1 registers");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_regs_map_free(&acb->reg_mu_acc_handle0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_unbind_handle(acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_mem_free(&acb->ccbs_acc_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* ARCMSR_MSGCODE_RWBUFFER */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)iop_mu_regs_map1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1110:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1120:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1130:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1160:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1170:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1210:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1220:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1230:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1231:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1260:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1261:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1270:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1280:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1212:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1222:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1380:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1381:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1680:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1681:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t *iop_mu_regs_map0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->adapter_type = ACB_ADAPTER_TYPE_A; /* intel */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dma_sync_size = ARCMSR_MAX_FREECCB_NUM * realccb_size + 0x20;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_regs_map_setup(acb->dev_info, 1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (caddr_t *)&iop_mu_regs_map0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct HBA_msgUnit), &acb->dev_acc_attr,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->reg_mu_acc_handle0) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "unable to map registers");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((i = ddi_dma_alloc_handle(acb->dev_info, &arcmsr_ccb_attr,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SLEEP, NULL, &acb->ccbs_pool_handle)) !=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_alloc_handle failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_regs_map_free(&acb->reg_mu_acc_handle0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_mem_alloc(acb->ccbs_pool_handle, dma_sync_size,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->dev_acc_attr, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SLEEP, NULL, (caddr_t *)&arcmsr_ccbs_area,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &allocated_length, &acb->ccbs_acc_handle) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_mem_alloc failed", instance);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_regs_map_free(&acb->reg_mu_acc_handle0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_addr_bind_handle(acb->ccbs_pool_handle, NULL,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (caddr_t)arcmsr_ccbs_area, dma_sync_size, DDI_DMA_RDWR |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &acb->ccb_cookie,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &count) != DDI_DMA_MAPPED) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_dma_addr_bind_handle failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_mem_free(&acb->ccbs_acc_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_regs_map_free(&acb->reg_mu_acc_handle0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero(arcmsr_ccbs_area, dma_sync_size);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore offset = (uint32_t)(P2ROUNDUP(PtrToNum(arcmsr_ccbs_area), 32)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore - PtrToNum(arcmsr_ccbs_area));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccbs_area = arcmsr_ccbs_area + offset;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* ioport base */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->pmu = (struct msgUnit *)(intptr_t)iop_mu_regs_map0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "Unknown RAID adapter type!");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_init_list_head(&acb->ccb_complete_list);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* here we can not access pci configuration again */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ACB_F_MESSAGE_RQBUFFER_CLEARED | ACB_F_MESSAGE_WQBUFFER_READ);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* physical address of acb->pccb_pool */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_phyaddr = acb->ccb_cookie.dmac_address + offset;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pccb_tmp = (struct CCB *)(intptr_t)arcmsr_ccbs_area;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pccb_tmp->cdb_phyaddr_pattern =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (acb->adapter_type == ACB_ADAPTER_TYPE_C) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_phyaddr : (cdb_phyaddr >> 5);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pccb_tmp->acb = acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->ccbworkingQ[i] = acb->pccb_pool[i] = pccb_tmp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_phyaddr = cdb_phyaddr + realccb_size;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pccb_tmp = (struct CCB *)NumToPtr(PtrToNum(pccb_tmp) +
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore realccb_size);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->vir2phy_offset = PtrToNum(pccb_tmp) - cdb_phyaddr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* disable all outbound interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = arcmsr_disable_allintr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_iop_confirm(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "arcmsr_iop_confirm error", instance);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_mem_free(&acb->ccbs_acc_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (id = 0; id < ARCMSR_MAX_TARGETID; id++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->devstate[id][lun] = ARECA_RAID_GONE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* enable outbound Post Queue, outbound doorbell Interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_do_ddi_attach(dev_info_t *dev_info, int instance)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_tran_t *hba_trans;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_device_acc_attr_t dev_acc_attr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint16_t wval;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int raid6 = 1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *type;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int intr_types;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Soft State Structure
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * The driver should allocate the per-device-instance
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * soft state structure, being careful to clean up properly if
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * an error occurs. Allocate data structure.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_soft_state_zalloc(arcmsr_soft_state, instance) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(NULL, "ddi_soft_state_zalloc failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb = ddi_get_soft_state(arcmsr_soft_state, instance);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ASSERT(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_mutex_init(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* acb is already zalloc()d so we don't need to bzero() it */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_acc_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_acc_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_acc_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->dev_info = dev_info;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->dev_acc_attr = dev_acc_attr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * The driver, if providing DMA, should also check that its hardware is
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * installed in a DMA-capable slot
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_slaveonly(dev_info) == DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "hardware is not installed in"
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore " a DMA-capable slot");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (pci_config_setup(dev_info, &acb->pci_acc_handle) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "pci_config_setup() failed, attach failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore wval = pci_config_get16(acb->pci_acc_handle, PCI_CONF_VENID);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (wval != PCI_VENDOR_ID_ARECA) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "'vendorid (0x%04x) does not match 0x%04x "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "(PCI_VENDOR_ID_ARECA)",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore wval, PCI_VENDOR_ID_ARECA);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore wval = pci_config_get16(acb->pci_acc_handle, PCI_CONF_DEVID);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (wval) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1110:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1210:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1201:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore raid6 = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*FALLTHRU*/
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1120:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1130:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1160:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1170:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1220:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1230:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1260:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1270:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1280:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type = "SATA 3G";
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1380:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1381:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1680:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1681:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type = "SAS 3G";
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case PCI_DEVICE_ID_ARECA_1880:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type = "SAS 6G";
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type = "X-TYPE";
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "Unknown Host Adapter RAID Controller!");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_CONT, "Areca %s Host Adapter RAID Controller%s\n",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore type, raid6 ? " (RAID6 capable)" : "");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* we disable iop interrupt here */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_initialize(acb) == DDI_FAILURE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "arcmsr_initialize failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Allocate a transport structure */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans = scsi_hba_tran_alloc(dev_info, SCSI_HBA_CANSLEEP);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (hba_trans == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "scsi_hba_tran_alloc failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_2;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->scsi_hba_transport = hba_trans;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->dev_info = dev_info;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* init scsi host adapter transport entry */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_hba_private = acb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_tgt_private = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * If no per-target initialization is required, the HBA can leave
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * tran_tgt_init set to NULL.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_tgt_init = arcmsr_tran_tgt_init;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_tgt_probe = scsi_hba_probe;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_tgt_free = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_start = arcmsr_tran_start;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_abort = arcmsr_tran_abort;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_reset = arcmsr_tran_reset;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_getcap = arcmsr_tran_getcap;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_setcap = arcmsr_tran_setcap;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_init_pkt = arcmsr_tran_init_pkt;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_destroy_pkt = arcmsr_tran_destroy_pkt;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_dmafree = arcmsr_tran_dmafree;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_sync_pkt = arcmsr_tran_sync_pkt;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_reset_notify = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_get_bus_addr = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_get_name = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_quiesce = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_unquiesce = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_bus_reset = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_bus_config = arcmsr_tran_bus_config;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_add_eventcall = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_get_eventcookie = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_post_event = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans->tran_remove_eventcall = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* iop init and enable interrupt here */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop_init(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Get supported interrupt types */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_intr_get_supported_types(dev_info, &intr_types) !=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_intr_get_supported_types failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_3;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (intr_types & DDI_INTR_TYPE_FIXED) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_add_intr(acb, DDI_INTR_TYPE_FIXED) != DDI_SUCCESS)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_5;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else if (intr_types & DDI_INTR_TYPE_MSI) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_add_intr(acb, DDI_INTR_TYPE_FIXED) != DDI_SUCCESS)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_5;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * The driver should attach this instance of the device, and
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * perform error cleanup if necessary
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (scsi_hba_attach_setup(dev_info, &arcmsr_dma_attr,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore hba_trans, SCSI_HBA_TRAN_CLONE) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "scsi_hba_attach_setup failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_5;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Create a taskq for dealing with dr events */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((acb->taskq = ddi_taskq_create(dev_info, "arcmsr_dr_taskq", 1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore TASKQ_DEFAULTPRI, 0)) == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ddi_taskq_create failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto error_level_8;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_count = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* active ccbs "timeout" watchdog */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_id = timeout(arcmsr_ccbs_timeout, (caddr_t)acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (ARCMSR_TIMEOUT_WATCH * drv_usectohz(1000000)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_sc_id = timeout(arcmsr_devMap_monitor, (caddr_t)acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (ARCMSR_DEV_MAP_WATCH * drv_usectohz(1000000)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* report device info */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_report_dev(dev_info);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (DDI_SUCCESS);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoreerror_level_8:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoreerror_level_7:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoreerror_level_6:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) scsi_hba_detach(dev_info);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoreerror_level_5:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_remove_intr(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoreerror_level_3:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoreerror_level_4:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->scsi_hba_transport)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_hba_tran_free(acb->scsi_hba_transport);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoreerror_level_2:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->ccbs_acc_handle)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_mem_free(&acb->ccbs_acc_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->ccbs_pool_handle)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_dma_free_handle(&acb->ccbs_pool_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoreerror_level_1:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->pci_acc_handle)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pci_config_teardown(&acb->pci_acc_handle);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_mutex_destroy(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_soft_state_free(arcmsr_soft_state, instance);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoreerror_level_0:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_FAILURE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_vlog(struct ACB *acb, int level, char *fmt, va_list ap)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char buf[256];
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb != NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) snprintf(buf, sizeof (buf), "%s%d: %s",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_driver_name(acb->dev_info),
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_get_instance(acb->dev_info), fmt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore fmt = buf;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore vcmn_err(level, fmt, ap);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_log(struct ACB *acb, int level, char *fmt, ...)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore va_list ap;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore va_start(ap, fmt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_vlog(acb, level, fmt, ap);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore va_end(ap);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_warn(struct ACB *acb, char *fmt, ...)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore va_list ap;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore va_start(ap, fmt);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_vlog(acb, CE_WARN, fmt, ap);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore va_end(ap);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_init_list_head(struct list_head *list)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore list->next = list;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore list->prev = list;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_x_list_del(struct list_head *prev, struct list_head *next)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore next->prev = prev;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore prev->next = next;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_x_list_add(struct list_head *new_one, struct list_head *prev,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct list_head *next)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore next->prev = new_one;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore new_one->next = next;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore new_one->prev = prev;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore prev->next = new_one;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_list_add_tail(kmutex_t *list_lock, struct list_head *new_one,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct list_head *head)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(list_lock);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_x_list_add(new_one, head->prev, head);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(list_lock);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic struct list_head *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_list_get_first(kmutex_t *list_lock, struct list_head *head)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct list_head *one = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(list_lock);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (head->next == head) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(list_lock);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore one = head->next;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_x_list_del(one->prev, one->next);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_init_list_head(one);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(list_lock);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (one);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic struct CCB *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_get_complete_ccb_from_list(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct list_head *first_complete_ccb_list = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore first_complete_ccb_list =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_list_get_first(&acb->ccb_complete_list_mutex,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &acb->ccb_complete_list);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (first_complete_ccb_list == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = (void *)((caddr_t)(first_complete_ccb_list) -
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore offsetof(struct CCB, complete_queue_pointer));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (ccb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic struct CCB *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_get_freeccb(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int ccb_get_index, ccb_put_index;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->workingQ_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_put_index = acb->ccb_put_index;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_get_index = acb->ccb_get_index;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = acb->ccbworkingQ[ccb_get_index];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_get_index++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb_get_index >= ARCMSR_MAX_FREECCB_NUM)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_get_index = ccb_get_index - ARCMSR_MAX_FREECCB_NUM;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb_put_index != ccb_get_index) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->ccb_get_index = ccb_get_index;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_init_list_head(&ccb->complete_queue_pointer);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state = ARCMSR_CCB_UNBUILD;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->workingQ_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_free_ccb(struct CCB *ccb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb = ccb->acb;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state == ARCMSR_CCB_FREE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->workingQ_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state = ARCMSR_CCB_FREE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt_dma_handle = NULL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_flags = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->ccbworkingQ[acb->ccb_put_index] = ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->ccb_put_index++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->ccb_put_index >= ARCMSR_MAX_FREECCB_NUM)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->ccb_put_index =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->ccb_put_index - ARCMSR_MAX_FREECCB_NUM;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->workingQ_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_ccbs_timeout(void* arg)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb = (struct ACB *)arg;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int i, instance, timeout_count = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t intmask_org;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore time_t current_time = ddi_get_time();
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = arcmsr_disable_allintr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->ccboutstandingcount != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check each ccb */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore i = ddi_dma_sync(acb->ccbs_pool_handle, 0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SYNC_FORKERNEL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (i != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((acb->timeout_id != 0) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* do pkt timeout check each 60 secs */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_id = timeout(arcmsr_ccbs_timeout,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void*)acb, (ARCMSR_TIMEOUT_WATCH *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore drv_usectohz(1000000)));
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore instance = ddi_get_instance(acb->dev_info);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = acb->pccb_pool[i];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->acb != acb) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state == ARCMSR_CCB_FREE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->pkt == NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->pkt->pkt_time == 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_time >= current_time) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int id = ccb->pkt->pkt_address.a_target;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int lun = ccb->pkt->pkt_address.a_lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state == ARCMSR_CCB_START) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *cdb = (uint8_t *)&ccb->arcmsr_cdb.Cdb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore timeout_count++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "scsi target %d lun %d cmd=0x%x "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "command timeout, ccb=0x%p",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore instance, id, lun, *cdb, (void *)ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state = ARCMSR_CCB_TIMEOUT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_TIMEOUT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_statistics = STAT_TIMEOUT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* acb->devstate[id][lun] = ARECA_RAID_GONE; */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccb_complete(ccb, 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else if ((ccb->ccb_state & ARCMSR_CCB_CAN_BE_FREE) ==
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_CCB_CAN_BE_FREE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_free_ccb(ccb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((acb->timeout_id != 0) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* do pkt timeout check each 60 secs */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_id = timeout(arcmsr_ccbs_timeout,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void*)acb, (ARCMSR_TIMEOUT_WATCH * drv_usectohz(1000000)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_abort_dr_ccbs(struct ACB *acb, uint16_t target, uint8_t lun)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t intmask_org;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int i;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* disable all outbound interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = arcmsr_disable_allintr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = acb->pccb_pool[i];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state == ARCMSR_CCB_START) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((target == ccb->pkt->pkt_address.a_target) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (lun == ccb->pkt->pkt_address.a_lun)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state = ARCMSR_CCB_ABORTED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_ABORTED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_statistics |= STAT_ABORTED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccb_complete(ccb, 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_NOTE,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "abort T%dL%d ccb", target, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* enable outbound Post Queue, outbound doorbell Interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_scsi_device_probe(struct ACB *acb, uint16_t tgt, uint8_t lun)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_device sd;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_info_t *child;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int rval;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero(&sd, sizeof (struct scsi_device));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sd.sd_address.a_hba_tran = acb->scsi_hba_transport;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sd.sd_address.a_target = (uint16_t)tgt;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sd.sd_address.a_lun = (uint8_t)lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((child = arcmsr_find_child(acb, tgt, lun)) != NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = scsi_hba_probe(&sd, NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (rval == SCSIPROBE_EXISTS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = ndi_devi_online(child, NDI_ONLINE_ATTACH);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (rval != NDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "unable to online T%dL%d",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore tgt, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_NOTE, "T%dL%d onlined",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore tgt, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = scsi_hba_probe(&sd, NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (rval == SCSIPROBE_EXISTS)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rval = arcmsr_config_child(acb, &sd, NULL);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore scsi_unprobe(&sd);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (rval);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_dr_handle(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *acb_dev_map = (char *)acb->device_map;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *devicemap;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char temp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint16_t target;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t lun;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char diff;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int circ = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dev_info_t *dip;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ddi_acc_handle_t reg;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore devicemap = (char *)&phbamu->msgcode_rwbuffer[21];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore reg = acb->reg_mu_acc_handle0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore devicemap = (char *)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[21];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore reg = acb->reg_mu_acc_handle1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore devicemap = (char *)&phbcmu->msgcode_rwbuffer[21];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore reg = acb->reg_mu_acc_handle0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore temp = CHIP_REG_READ8(reg, devicemap);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore diff = (*acb_dev_map)^ temp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (diff != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *acb_dev_map = temp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((temp & 0x01) == 1 && (diff & 0x01) == 1) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ndi_devi_enter(acb->dev_info, &circ);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->devstate[target][lun] =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARECA_RAID_GOOD;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) arcmsr_scsi_device_probe(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore target, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ndi_devi_exit(acb->dev_info, circ);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_NOTE,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "T%dL%d on-line", target, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else if ((temp & 0x01) == 0 &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (diff & 0x01) == 1) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dip = arcmsr_find_child(acb, target,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (dip != NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->devstate[target][lun] =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARECA_RAID_GONE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (mutex_owned(&acb->
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isr_mutex)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_abort_dr_ccbs(
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb, target, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ndi_devi_offline(
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dip,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore NDI_DEVI_REMOVE |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore NDI_DEVI_OFFLINE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_abort_dr_ccbs(
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb, target, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ndi_devi_offline(
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore dip,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore NDI_DEVI_REMOVE |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore NDI_DEVI_OFFLINE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_NOTE,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "T%dL%d off-line", target, lun);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore temp >>= 1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore diff >>= 1;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore devicemap++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb_dev_map++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_devMap_monitor(void* arg)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb = (struct ACB *)arg;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->inbound_msgaddr0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_MESG0_GET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_GET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_msgaddr0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_MESG0_GET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((acb->timeout_id != 0) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* do pkt timeout check each 5 secs */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_id = timeout(arcmsr_devMap_monitor, (void*)acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (ARCMSR_DEV_MAP_WATCH * drv_usectohz(1000000)));
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint32_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_disable_allintr(struct ACB *acb) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t intmask_org;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* disable all outbound interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intmask);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intmask,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* disable all outbound interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell_mask);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* disable all interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell_mask, 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* disable all outbound interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->host_int_mask); /* disable outbound message0 int */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->host_int_mask,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org|ARCMSR_HBCMU_ALL_INTMASKENABLE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (intmask_org);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_enable_allintr(struct ACB *acb, uint32_t intmask_org) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int mask;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson switch (acb->adapter_type) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ACB_ADAPTER_TYPE_A:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * enable outbound Post Queue, outbound doorbell message0
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Interrupt
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intmask, intmask_org & mask);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ACB_ADAPTER_TYPE_B:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mask = (ARCMSR_IOP2DRV_DATA_WRITE_OK |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_IOP2DRV_DATA_READ_OK | ARCMSR_IOP2DRV_CDB_DONE |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_IOP2DRV_MESSAGE_CMD_DONE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* 1=interrupt enable, 0=interrupt disable */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell_mask,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org | mask);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* enable outbound Post Queue,outbound doorbell Interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mask = ~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->host_int_mask, intmask_org & mask);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_iop_parking(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* stop adapter background rebuild */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->acb_flags & ACB_F_MSG_START_BGRB) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t intmask_org;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* disable all outbound interrupt */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson intmask_org = arcmsr_disable_allintr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_stop_hba_bgrb(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hba_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_stop_hbb_bgrb(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hbb_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_stop_hbc_bgrb(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hbc_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * enable outbound Post Queue
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * enable outbound doorbell Interrupt
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_enable_allintr(acb, intmask_org);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hba_wait_msgint_ready(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t i;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t retries = 0x00;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore do {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < 100; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intstatus) &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intstatus,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MU_OUTBOUND_MESSAGE0_INT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRUE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore drv_usecwait(10000);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_in_panic()) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intstatus,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MU_OUTBOUND_MESSAGE0_INT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRUE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } /* max 1 second */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } while (retries++ < 20); /* max 20 seconds */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (FALSE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hbb_wait_msgint_ready(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t i;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t retries = 0x00;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore do {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < 100; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell) &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DRV2IOP_END_OF_INTERRUPT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRUE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore drv_usecwait(10000);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_in_panic()) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DRV2IOP_END_OF_INTERRUPT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRUE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } /* max 1 second */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } while (retries++ < 20); /* max 20 seconds */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (FALSE);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hbc_wait_msgint_ready(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t i;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t retries = 0x00;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t c = ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore do {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < 100; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_doorbell) &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_doorbell_clear, c);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRUE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore drv_usecwait(10000);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_in_panic()) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_doorbell_clear, c);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRUE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } /* max 1 second */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } while (retries++ < 20); /* max 20 seconds */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (FALSE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_flush_hba_cache(struct ACB *acb) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int retry_count = 30;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* enlarge wait flush adapter cache time: 10 minutes */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbamu->inbound_msgaddr0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore do {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_hba_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retry_count--;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } while (retry_count != 0);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_flush_hbb_cache(struct ACB *acb) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int retry_count = 30;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* enlarge wait flush adapter cache time: 10 minutes */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_FLUSH_CACHE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore do {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_hbb_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retry_count--;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } while (retry_count != 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_flush_hbc_cache(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int retry_count = 30;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* enlarge wait flush adapter cache time: 10 minutes */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbcmu->inbound_msgaddr0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbcmu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore do {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (arcmsr_hbc_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retry_count--;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } while (retry_count != 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_abort_hba_allcmd(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu = (struct HBA_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbamu->inbound_msgaddr0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_MESG0_ABORT_CMD);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hba_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for 'abort all "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "outstanding commands'");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (0xff);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (0x00);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_abort_hbb_allcmd(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu = (struct HBB_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell, ARCMSR_MESSAGE_ABORT_CMD);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbb_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for 'abort all "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "outstanding commands'");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (0x00);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (0x00);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_abort_hbc_allcmd(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbcmu->inbound_msgaddr0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_MESG0_ABORT_CMD);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbcmu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbc_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for 'abort all "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "outstanding commands'");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (0xff);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (0x00);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_done4abort_postqueue(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t flag_ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int i = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore boolean_t error;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson switch (acb->adapter_type) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ACB_ADAPTER_TYPE_A:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBA_msgUnit *phbamu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t outbound_intstatus;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear and abort all outbound posted Q */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_intstatus = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intstatus) & acb->outbound_int_enable;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear interrupt */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intstatus, outbound_intstatus);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while (((flag_ccb = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_queueport)) != 0xFFFFFFFF) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* frame must be 32 bytes aligned */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* the CDB is the first field of the CCB */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = NumToPtr((acb->vir2phy_offset + (flag_ccb << 5)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check if command done with no error */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore B_TRUE : B_FALSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_drain_donequeue(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ACB_ADAPTER_TYPE_B:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear all outbound posted Q */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear doorbell interrupt */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DOORBELL_INT_CLEAR_PATTERN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((flag_ccb = phbbmu->done_qbuffer[i]) != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->done_qbuffer[i] = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* frame must be 32 bytes aligned */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = NumToPtr((acb->vir2phy_offset +
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (flag_ccb << 5)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check if command done with no error */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore error =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (flag_ccb &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore B_TRUE : B_FALSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_drain_donequeue(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->post_qbuffer[i] = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } /* drain reply FIFO */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->doneq_index = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->postq_index = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t ccb_cdb_phy;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while ((CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->host_int_status) &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* need to do */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore flag_ccb = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_queueport_low);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* frame must be 32 bytes aligned */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = NumToPtr((acb->vir2phy_offset + ccb_cdb_phy));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1)?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore B_TRUE : B_FALSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_drain_donequeue(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Routine Description: try to get echo from iop.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Arguments:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return Value: Nothing.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_get_echo_from_iop(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t intmask_org;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t rtnval = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = arcmsr_disable_allintr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->inbound_msgaddr0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_MESG0_GET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hba_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "try to get echo from iop,"
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "... timeout ...");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags |= ACB_F_BUS_HANG_ON;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rtnval = 0xFF;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* enable all outbound interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (rtnval);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Routine Description: Reset 80331 iop.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Arguments:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Return Value: Nothing.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_iop_reset(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t intmask_org;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t rtnval = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int i = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->ccboutstandingcount > 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* disable all outbound interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = arcmsr_disable_allintr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear and abort all outbound posted Q */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_done4abort_postqueue(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* talk to iop 331 outstanding command aborted */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rtnval = (acb->acb_flags & ACB_F_BUS_HANG_ON) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore 0xFF : arcmsr_abort_host_command(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = acb->pccb_pool[i];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state == ARCMSR_CCB_START) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* ccb->ccb_state = ARCMSR_CCB_RESET; */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_RESET;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_statistics |= STAT_BUS_RESET;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccb_complete(ccb, 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore atomic_and_32(&acb->ccboutstandingcount, 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* enable all outbound interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rtnval = arcmsr_get_echo_from_iop(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (rtnval);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic struct QBUFFER *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_get_iop_rqbuffer(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct QBUFFER *qb;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore qb = (struct QBUFFER *)&phbamu->message_rbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore qb = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_rbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore qb = (struct QBUFFER *)&phbcmu->message_rbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (qb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic struct QBUFFER *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_get_iop_wqbuffer(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct QBUFFER *qbuffer = NULL;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore qbuffer = (struct QBUFFER *)&phbamu->message_wbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore qbuffer = (struct QBUFFER *)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->message_wbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (qbuffer);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_iop_message_read(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* let IOP know the data has been read */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* let IOP know the data has been read */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DRV2IOP_DATA_READ_OK);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* let IOP know data has been read */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_iop_message_wrote(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A: {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * push inbound doorbell tell iop, driver data write ok
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * and wait reply on next hwinterrupt for next Qbuffer post
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * push inbound doorbell tell iop, driver data was writen
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * successfully, then await reply on next hwinterrupt for
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * next Qbuffer post
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DRV2IOP_DATA_WRITE_OK);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * push inbound doorbell tell iop, driver data write ok
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * and wait reply on next hwinterrupt for next Qbuffer post
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_post_ioctldata2iop(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *pQbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct QBUFFER *pwbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *iop_data;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int32_t allxfer_len = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pwbuffer = arcmsr_get_iop_wqbuffer(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_data = (uint8_t *)pwbuffer->data;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while ((acb->wqbuf_firstidx != acb->wqbuf_lastidx) &&
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (allxfer_len < 124)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pQbuffer = &acb->wqbuffer[acb->wqbuf_firstidx];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memcpy(iop_data, pQbuffer, 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->wqbuf_firstidx++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* if last index number set it to 0 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->wqbuf_firstidx %= ARCMSR_MAX_QBUFFER;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_data++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore allxfer_len++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pwbuffer->data_len = allxfer_len;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * push inbound doorbell and wait reply at hwinterrupt
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * routine for next Qbuffer post
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop_message_wrote(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_stop_hba_bgrb(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hba_wait_msgint_ready(acb))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for background rebuild completion");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_stop_hbb_bgrb(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell, ARCMSR_MESSAGE_STOP_BGRB);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbb_wait_msgint_ready(acb))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for background rebuild completion");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_stop_hbc_bgrb(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbc_wait_msgint_ready(acb))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for background rebuild completion");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic int
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_iop_message_xfer(struct ACB *acb, struct scsi_pkt *pkt)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CMD_MESSAGE_FIELD *pcmdmessagefld;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb = pkt->pkt_ha_private;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct buf *bp = ccb->bp;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *pQbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int retvalue = 0, transfer_len = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *buffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t controlcode;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* 4 bytes: Areca io control code */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore controlcode =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (uint32_t)pkt->pkt_cdbp[5] << 24 |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (uint32_t)pkt->pkt_cdbp[6] << 16 |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (uint32_t)pkt->pkt_cdbp[7] << 8 |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (uint32_t)pkt->pkt_cdbp[8];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (bp->b_flags & (B_PHYS | B_PAGEIO))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bp_mapin(bp);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore buffer = bp->b_un.b_addr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore transfer_len = bp->b_bcount;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (transfer_len > sizeof (struct CMD_MESSAGE_FIELD)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ARCMSR_MESSAGE_FAIL;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto message_out;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pcmdmessagefld = (struct CMD_MESSAGE_FIELD *)(intptr_t)buffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (controlcode) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ARCMSR_MESSAGE_READ_RQBUFFER:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson unsigned long *ver_addr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *ptmpQbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int32_t allxfer_len = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ver_addr = kmem_zalloc(MSGDATABUFLEN, KM_SLEEP);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ptmpQbuffer = (uint8_t *)ver_addr;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson while ((acb->rqbuf_firstidx != acb->rqbuf_lastidx) &&
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (allxfer_len < (MSGDATABUFLEN - 1))) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson pQbuffer = &acb->rqbuffer[acb->rqbuf_firstidx];
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (void) memcpy(ptmpQbuffer, pQbuffer, 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->rqbuf_firstidx++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->rqbuf_firstidx %= ARCMSR_MAX_QBUFFER;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ptmpQbuffer++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson allxfer_len++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct QBUFFER *prbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *iop_data;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int32_t iop_len;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson prbuffer = arcmsr_get_iop_rqbuffer(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_data = (uint8_t *)prbuffer->data;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_len = (int32_t)prbuffer->data_len;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson while (iop_len > 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson pQbuffer = &acb->rqbuffer[acb->rqbuf_lastidx];
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (void) memcpy(pQbuffer, iop_data, 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->rqbuf_lastidx++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->rqbuf_lastidx %= ARCMSR_MAX_QBUFFER;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_data++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_len--;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_iop_message_read(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memcpy(pcmdmessagefld->messagedatabuffer,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (uint8_t *)ver_addr, allxfer_len);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pcmdmessagefld->cmdmessage.Length = allxfer_len;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pcmdmessagefld->cmdmessage.ReturnCode =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ARCMSR_MESSAGE_RETURNCODE_OK;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson kmem_free(ver_addr, MSGDATABUFLEN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ARCMSR_MESSAGE_WRITE_WQBUFFER:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *ver_addr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int32_t my_empty_len, user_len, wqbuf_firstidx,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore wqbuf_lastidx;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t *ptmpuserbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ver_addr = kmem_zalloc(MSGDATABUFLEN, KM_SLEEP);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ptmpuserbuffer = ver_addr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore user_len = min(pcmdmessagefld->cmdmessage.Length,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore MSGDATABUFLEN);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (void) memcpy(ptmpuserbuffer,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pcmdmessagefld->messagedatabuffer, user_len);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson wqbuf_lastidx = acb->wqbuf_lastidx;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson wqbuf_firstidx = acb->wqbuf_firstidx;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (wqbuf_lastidx != wqbuf_firstidx) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_arq_status *arq_status;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_post_ioctldata2iop(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status = (struct scsi_arq_status *)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (intptr_t)(pkt->pkt_scbp);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero((caddr_t)arq_status,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct scsi_arq_status));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_reason = CMD_CMPLT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_state = (STATE_GOT_BUS |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore STATE_GOT_TARGET | STATE_SENT_CMD |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore STATE_XFERRED_DATA | STATE_GOT_STATUS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_statistics =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_statistics;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_resid = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (&arq_status->sts_sensedata != NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_extended_sense *sts_sensedata;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata = &arq_status->sts_sensedata;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* has error report sensedata */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_code = 0x0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_valid = 0x01;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_key = KEY_ILLEGAL_REQUEST;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* AdditionalSenseLength */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_add_len = 0x0A;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* AdditionalSenseCode */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_add_code = 0x20;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ARCMSR_MESSAGE_FAIL;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore my_empty_len = (wqbuf_firstidx-wqbuf_lastidx - 1) &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (ARCMSR_MAX_QBUFFER - 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (my_empty_len >= user_len) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while (user_len > 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pQbuffer = &acb->wqbuffer[
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->wqbuf_lastidx];
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (void) memcpy(pQbuffer,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ptmpuserbuffer, 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->wqbuf_lastidx++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->wqbuf_lastidx %=
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ARCMSR_MAX_QBUFFER;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ptmpuserbuffer++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson user_len--;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (acb->acb_flags &
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ACB_F_MESSAGE_WQBUFFER_CLEARED) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags &=
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_post_ioctldata2iop(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_arq_status *arq_status;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* has error report sensedata */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status = (struct scsi_arq_status *)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (intptr_t)(pkt->pkt_scbp);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore bzero((caddr_t)arq_status,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sizeof (struct scsi_arq_status));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_reason = CMD_CMPLT;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_state =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (STATE_GOT_BUS |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore STATE_GOT_TARGET |STATE_SENT_CMD |
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore STATE_XFERRED_DATA | STATE_GOT_STATUS);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_statistics =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pkt->pkt_statistics;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arq_status->sts_rqpkt_resid = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (&arq_status->sts_sensedata != NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct scsi_extended_sense *
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &arq_status->sts_sensedata;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* has error report sensedata */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_code = 0x0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_valid = 0x01;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_key =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore KEY_ILLEGAL_REQUEST;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* AdditionalSenseLength */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_add_len = 0x0A;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* AdditionalSenseCode */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sts_sensedata->es_add_code = 0x20;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ARCMSR_MESSAGE_FAIL;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson kmem_free(ver_addr, MSGDATABUFLEN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ARCMSR_MESSAGE_CLEAR_RQBUFFER:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pQbuffer = acb->rqbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop_message_read(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->rqbuf_firstidx = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->rqbuf_lastidx = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pcmdmessagefld->cmdmessage.ReturnCode =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ARCMSR_MESSAGE_RETURNCODE_OK;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ARCMSR_MESSAGE_CLEAR_WQBUFFER:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pQbuffer = acb->wqbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_iop_message_read(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ACB_F_MESSAGE_WQBUFFER_READ);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->wqbuf_firstidx = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->wqbuf_lastidx = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pcmdmessagefld->cmdmessage.ReturnCode =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ARCMSR_MESSAGE_RETURNCODE_OK;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_iop_message_read(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ACB_F_MESSAGE_RQBUFFER_CLEARED |
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ACB_F_MESSAGE_WQBUFFER_READ);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->rqbuf_firstidx = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->rqbuf_lastidx = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->wqbuf_firstidx = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->wqbuf_lastidx = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson pQbuffer = acb->rqbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memset(pQbuffer, 0, sizeof (struct QBUFFER));
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson pQbuffer = acb->wqbuffer;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) memset(pQbuffer, 0, sizeof (struct QBUFFER));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pcmdmessagefld->cmdmessage.ReturnCode =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ARCMSR_MESSAGE_RETURNCODE_OK;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ARCMSR_MESSAGE_REQUEST_RETURN_CODE_3F:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pcmdmessagefld->cmdmessage.ReturnCode =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ARCMSR_MESSAGE_RETURNCODE_3F;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Not supported - ARCMSR_MESSAGE_SAY_HELLO
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ARCMSR_MESSAGE_SAY_GOODBYE:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_iop_parking(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_flush_hba_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_flush_hbb_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hbc_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retvalue = ARCMSR_MESSAGE_FAIL;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amoremessage_out:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return (retvalue);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_pcidev_disattach(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct CCB *ccb;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int i = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* disable all outbound interrupts */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (void) arcmsr_disable_allintr(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* stop adapter background rebuild */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_stop_hba_bgrb(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_flush_hba_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_stop_hbb_bgrb(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_flush_hbb_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_stop_hbc_bgrb(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_flush_hbc_cache(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* abort all outstanding commands */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags |= ACB_F_SCSISTOPADAPTER;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags &= ~ACB_F_IOP_INITED;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (acb->ccboutstandingcount != 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* clear and abort all outbound posted Q */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_done4abort_postqueue(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* talk to iop outstanding command aborted */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) arcmsr_abort_host_command(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb = acb->pccb_pool[i];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state == ARCMSR_CCB_START) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* ccb->ccb_state = ARCMSR_CCB_ABORTED; */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt->pkt_reason = CMD_ABORTED;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt->pkt_statistics |= STAT_ABORTED;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_ccb_complete(ccb, 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/* get firmware miscellaneous data */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_get_hba_config(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson char *acb_firm_model;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson char *acb_firm_version;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi char *acb_device_map;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson char *iop_firm_model;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson char *iop_firm_version;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi char *iop_device_map;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int count;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbamu = (struct HBA_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb_firm_model = acb->firm_model;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb_firm_version = acb->firm_version;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi acb_device_map = acb->device_map;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* firm_model, 15 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_firm_model =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (char *)(&phbamu->msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* firm_version, 17 */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_firm_version =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (char *)(&phbamu->msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
ed632624009d91d344479bf05ec24b9e0772939bColin Yi /* device_map, 21 */
ed632624009d91d344479bf05ec24b9e0772939bColin Yi iop_device_map =
ed632624009d91d344479bf05ec24b9e0772939bColin Yi (char *)(&phbamu->msgcode_rwbuffer[ARCMSR_FW_MAP_OFFSET]);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (!arcmsr_hba_wait_msgint_ready(acb))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for adapter firmware "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "miscellaneous data");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson count = 8;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson while (count) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *acb_firm_model = CHIP_REG_READ8(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_firm_model);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb_firm_model++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_firm_model++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson count--;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson count = 16;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson while (count) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson *acb_firm_version =
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CHIP_REG_READ8(acb->reg_mu_acc_handle0, iop_firm_version);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb_firm_version++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_firm_version++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson count--;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
ed632624009d91d344479bf05ec24b9e0772939bColin Yi count = 16;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi while (count) {
ed632624009d91d344479bf05ec24b9e0772939bColin Yi *acb_device_map =
ed632624009d91d344479bf05ec24b9e0772939bColin Yi CHIP_REG_READ8(acb->reg_mu_acc_handle0, iop_device_map);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi acb_device_map++;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi iop_device_map++;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi count--;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_CONT, "ARECA RAID FIRMWARE VERSION %s\n",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_version);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* firm_request_len, 1 */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->firm_request_len = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &phbamu->msgcode_rwbuffer[1]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* firm_numbers_queue, 2 */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->firm_numbers_queue = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &phbamu->msgcode_rwbuffer[2]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* firm_sdram_size, 3 */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->firm_sdram_size = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &phbamu->msgcode_rwbuffer[3]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* firm_ide_channels, 4 */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->firm_ide_channels = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &phbamu->msgcode_rwbuffer[4]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/* get firmware miscellaneous data */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_get_hbb_config(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson char *acb_firm_model;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson char *acb_firm_version;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi char *acb_device_map;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson char *iop_firm_model;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson char *iop_firm_version;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi char *iop_device_map;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int count;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbbmu = (struct HBB_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb_firm_model = acb->firm_model;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb_firm_version = acb->firm_version;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi acb_device_map = acb->device_map;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* firm_model, 15 */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_firm_model = (char *)
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (&phbbmu->hbb_rwbuffer->msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* firm_version, 17 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_firm_version = (char *)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (&phbbmu->hbb_rwbuffer->msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* device_map, 21 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_device_map = (char *)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (&phbbmu->hbb_rwbuffer->msgcode_rwbuffer[ARCMSR_FW_MAP_OFFSET]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbb_wait_msgint_ready(acb))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for adapter firmware "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "miscellaneous data");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore count = 8;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while (count) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *acb_firm_model =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ8(acb->reg_mu_acc_handle1, iop_firm_model);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb_firm_model++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_firm_model++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore count--;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore count = 16;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while (count) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *acb_firm_version =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ8(acb->reg_mu_acc_handle1, iop_firm_version);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb_firm_version++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_firm_version++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore count--;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore count = 16;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while (count) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *acb_device_map =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ8(acb->reg_mu_acc_handle1, iop_device_map);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb_device_map++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_device_map++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore count--;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_CONT, "ARECA RAID FIRMWARE VERSION %s\n",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_version);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_request_len, 1 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_request_len = CHIP_REG_READ32(acb->reg_mu_acc_handle1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[1]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_numbers_queue, 2 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_numbers_queue = CHIP_REG_READ32(acb->reg_mu_acc_handle1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[2]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_sdram_size, 3 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_sdram_size = CHIP_REG_READ32(acb->reg_mu_acc_handle1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[3]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_ide_channels, 4 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_ide_channels = CHIP_REG_READ32(acb->reg_mu_acc_handle1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[4]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/* get firmware miscellaneous data */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_get_hbc_config(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *acb_firm_model;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *acb_firm_version;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *acb_device_map;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *iop_firm_model;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *iop_firm_version;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore char *iop_device_map;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int count;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb_firm_model = acb->firm_model;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb_firm_version = acb->firm_version;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb_device_map = acb->device_map;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_model, 15 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_firm_model =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (char *)(&phbcmu->msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_version, 17 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_firm_version =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (char *)(&phbcmu->msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi /* device_map, 21 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore iop_device_map =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (char *)(&phbcmu->msgcode_rwbuffer[ARCMSR_FW_MAP_OFFSET]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* post "get config" instruction */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbc_wait_msgint_ready(acb))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for adapter firmware "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "miscellaneous data");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson count = 8;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson while (count) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *acb_firm_model =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ8(acb->reg_mu_acc_handle0, iop_firm_model);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb_firm_model++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_firm_model++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson count--;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson count = 16;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson while (count) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore *acb_firm_version =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ8(acb->reg_mu_acc_handle0, iop_firm_version);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb_firm_version++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_firm_version++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson count--;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
ed632624009d91d344479bf05ec24b9e0772939bColin Yi count = 16;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi while (count) {
ed632624009d91d344479bf05ec24b9e0772939bColin Yi *acb_device_map =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ8(acb->reg_mu_acc_handle0, iop_device_map);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi acb_device_map++;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi iop_device_map++;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi count--;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_log(acb, CE_CONT, "ARECA RAID FIRMWARE VERSION %s\n",
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_version);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_request_len, 1, 04-07 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_request_len = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->msgcode_rwbuffer[1]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_numbers_queue, 2, 08-11 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_numbers_queue = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->msgcode_rwbuffer[2]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_sdram_size, 3, 12-15 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_sdram_size = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->msgcode_rwbuffer[3]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_ide_channels, 4, 16-19 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_ide_channels = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->msgcode_rwbuffer[4]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* firm_cfg_version, 25, 100-103 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->firm_cfg_version = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->msgcode_rwbuffer[25]);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/* start background rebuild */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonarcmsr_start_hba_bgrb(struct ACB *acb) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbamu = (struct HBA_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags |= ACB_F_MSG_START_BGRB;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &phbamu->inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (!arcmsr_hba_wait_msgint_ready(acb))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for background rebuild to start");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonarcmsr_start_hbb_bgrb(struct ACB *acb) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbbmu = (struct HBB_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags |= ACB_F_MSG_START_BGRB;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &phbbmu->hbb_doorbell->drv2iop_doorbell,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ARCMSR_MESSAGE_START_BGRB);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (!arcmsr_hbb_wait_msgint_ready(acb))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for background rebuild to start");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_start_hbc_bgrb(struct ACB *acb) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags |= ACB_F_MSG_START_BGRB;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbc_wait_msgint_ready(acb))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout while waiting for background rebuild to start");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_polling_hba_ccbdone(struct ACB *acb, struct CCB *poll_ccb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore boolean_t error;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t flag_ccb, outbound_intstatus, intmask_org;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore boolean_t poll_ccb_done = B_FALSE;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson uint32_t poll_count = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbamu = (struct HBA_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonpolling_ccb_retry:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* TODO: Use correct offset and size for syncing? */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_sync(acb->ccbs_pool_handle, 0, 0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DDI_DMA_SYNC_FORKERNEL) != DDI_SUCCESS)
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = arcmsr_disable_allintr(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (;;) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if ((flag_ccb = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &phbamu->outbound_queueport)) == 0xFFFFFFFF) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (poll_ccb_done) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* chip FIFO no ccb for completion already */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } else {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson drv_usecwait(25000);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi if ((poll_count > 100) && (poll_ccb != NULL)) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
ed632624009d91d344479bf05ec24b9e0772939bColin Yi if (acb->ccboutstandingcount == 0) {
ed632624009d91d344479bf05ec24b9e0772939bColin Yi break;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore poll_count++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_intstatus =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intstatus) &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->outbound_int_enable;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intstatus,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_intstatus); /* clear interrupt */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* frame must be 32 bytes aligned */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = NumToPtr((acb->vir2phy_offset + (flag_ccb << 5)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check if command done with no error */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore B_TRUE : B_FALSE;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi if (poll_ccb != NULL)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore poll_ccb_done = (ccb == poll_ccb) ? B_TRUE : B_FALSE;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->acb != acb) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ccb got a wrong acb!");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state != ARCMSR_CCB_START) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state & ARCMSR_ABNORMAL_MASK) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state |= ARCMSR_CCB_BACK;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt->pkt_reason = CMD_ABORTED;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt->pkt_statistics |= STAT_ABORTED;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_ccb_complete(ccb, 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson continue;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_report_ccb_state(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "polling op got unexpected ccb command done");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson continue;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_report_ccb_state(acb, ccb, error);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } /* drain reply FIFO */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_polling_hbb_ccbdone(struct ACB *acb, struct CCB *poll_ccb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t flag_ccb, intmask_org;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore boolean_t error;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson uint32_t poll_count = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int index;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore boolean_t poll_ccb_done = B_FALSE;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbbmu = (struct HBB_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonpolling_ccb_retry:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* Use correct offset and size for syncing */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_sync(acb->ccbs_pool_handle, 0, 0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson DDI_DMA_SYNC_FORKERNEL) != DDI_SUCCESS)
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson return;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = arcmsr_disable_allintr(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (;;) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson index = phbbmu->doneq_index;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if ((flag_ccb = phbbmu->done_qbuffer[index]) == 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (poll_ccb_done) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* chip FIFO no ccb for completion already */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } else {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson drv_usecwait(25000);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi if ((poll_count > 100) && (poll_ccb != NULL))
ed632624009d91d344479bf05ec24b9e0772939bColin Yi break;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi if (acb->ccboutstandingcount == 0)
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore poll_count++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear doorbell interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DOORBELL_INT_CLEAR_PATTERN);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbbmu->done_qbuffer[index] = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson index++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* if last index number set it to 0 */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson index %= ARCMSR_MAX_HBB_POSTQUEUE;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbbmu->doneq_index = index;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* check if command done with no error */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* frame must be 32 bytes aligned */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = NumToPtr((acb->vir2phy_offset + (flag_ccb << 5)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check if command done with no error */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore B_TRUE : B_FALSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
ed632624009d91d344479bf05ec24b9e0772939bColin Yi if (poll_ccb != NULL)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore poll_ccb_done = (ccb == poll_ccb) ? B_TRUE : B_FALSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->acb != acb) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ccb got a wrong acb!");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state != ARCMSR_CCB_START) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state & ARCMSR_ABNORMAL_MASK) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state |= ARCMSR_CCB_BACK;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt->pkt_reason = CMD_ABORTED;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson ccb->pkt->pkt_statistics |= STAT_ABORTED;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_ccb_complete(ccb, 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson continue;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_report_ccb_state(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "polling op got unexpect ccb command done");
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson continue;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_report_ccb_state(acb, ccb, error);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } /* drain reply FIFO */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_polling_hbc_ccbdone(struct ACB *acb, struct CCB *poll_ccb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore boolean_t error;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t ccb_cdb_phy;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t flag_ccb, intmask_org;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore boolean_t poll_ccb_done = B_FALSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t poll_count = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorepolling_ccb_retry:
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Use correct offset and size for syncing */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_sync(acb->ccbs_pool_handle, 0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SYNC_FORKERNEL) != DDI_SUCCESS)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = arcmsr_disable_allintr(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (;;) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!(CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->host_int_status) &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR)) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (poll_ccb_done) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* chip FIFO no ccb for completion already */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore drv_usecwait(25000);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((poll_count > 100) && (poll_ccb != NULL)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->ccboutstandingcount == 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore poll_count++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore flag_ccb = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_queueport_low);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* frame must be 32 bytes aligned */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* the CDB is the first field of the CCB */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = NumToPtr((acb->vir2phy_offset + ccb_cdb_phy));
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check if command done with no error */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore B_TRUE : B_FALSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (poll_ccb != NULL)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore poll_ccb_done = (ccb == poll_ccb) ? B_TRUE : B_FALSE;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->acb != acb) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "ccb got a wrong acb!");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state != ARCMSR_CCB_START) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ccb->ccb_state & ARCMSR_ABNORMAL_MASK) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->ccb_state |= ARCMSR_CCB_BACK;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_reason = CMD_ABORTED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb->pkt->pkt_statistics |= STAT_ABORTED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccb_complete(ccb, 1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_report_ccb_state(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "polling op got unexpected ccb command done");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore continue;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_report_ccb_state(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } /* drain reply FIFO */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_hba_hardware_reset()
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Bug Fix for Intel IOP cause firmware hang on.
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * and kernel panic
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hba_hardware_reset(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t value[64];
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int i;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* backup pci config data */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < 64; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore value[i] = pci_config_get8(acb->pci_acc_handle, i);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* hardware reset signal */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((PCI_DEVICE_ID_ARECA_1680 ==
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pci_config_get16(acb->pci_acc_handle, PCI_CONF_DEVID))) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->reserved1[0], 0x00000003);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } else {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pci_config_put8(acb->pci_acc_handle, 0x84, 0x20);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore drv_usecwait(1000000);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* write back pci config data */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore for (i = 0; i < 64; i++) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore pci_config_put8(acb->pci_acc_handle, i, value[i]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore drv_usecwait(1000000);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_abort_host_command
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint8_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_abort_host_command(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint8_t rtnval = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rtnval = arcmsr_abort_hba_allcmd(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rtnval = arcmsr_abort_hbb_allcmd(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore rtnval = arcmsr_abort_hbc_allcmd(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (rtnval);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Function: arcmsr_handle_iop_bus_hold
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_handle_iop_bus_hold(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int retry_count = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->timeout_count = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_hba_hardware_reset(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags &= ~ACB_F_IOP_INITED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore sleep_again:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore drv_usecwait(1000000);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_msgaddr1) &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (retry_count > 60) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "waiting for hardware"
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "bus reset return, RETRY TERMINATED!!");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retry_count++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore goto sleep_again;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop_init(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonarcmsr_iop2drv_data_wrote_handle(struct ACB *acb) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct QBUFFER *prbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson uint8_t *pQbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson uint8_t *iop_data;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int my_empty_len, iop_len;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int rqbuf_firstidx, rqbuf_lastidx;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* check this iop data if overflow my rqbuffer */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson rqbuf_lastidx = acb->rqbuf_lastidx;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson rqbuf_firstidx = acb->rqbuf_firstidx;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson prbuffer = arcmsr_get_iop_rqbuffer(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_data = (uint8_t *)prbuffer->data;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_len = prbuffer->data_len;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson my_empty_len = (rqbuf_firstidx-rqbuf_lastidx - 1) &
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (ARCMSR_MAX_QBUFFER - 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (my_empty_len >= iop_len) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson while (iop_len > 0) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson pQbuffer = &acb->rqbuffer[rqbuf_lastidx];
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (void) memcpy(pQbuffer, iop_data, 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson rqbuf_lastidx++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* if last index number set it to 0 */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson rqbuf_lastidx %= ARCMSR_MAX_QBUFFER;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_data++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_len--;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->rqbuf_lastidx = rqbuf_lastidx;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_iop_message_read(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* signature, let IOP know data has been read */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson } else {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonarcmsr_iop2drv_data_read_handle(struct ACB *acb) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READ;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * check if there are any mail packages from user space program
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * in my post bag, now is the time to send them into Areca's firmware
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (acb->wqbuf_firstidx != acb->wqbuf_lastidx) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson uint8_t *pQbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct QBUFFER *pwbuffer;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson uint8_t *iop_data;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson int allxfer_len = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson pwbuffer = arcmsr_get_iop_wqbuffer(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_data = (uint8_t *)pwbuffer->data;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson while ((acb->wqbuf_firstidx != acb->wqbuf_lastidx) &&
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (allxfer_len < 124)) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson pQbuffer = &acb->wqbuffer[acb->wqbuf_firstidx];
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson (void) memcpy(iop_data, pQbuffer, 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->wqbuf_firstidx++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* if last index number set it to 0 */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->wqbuf_firstidx %= ARCMSR_MAX_QBUFFER;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson iop_data++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson allxfer_len++;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson pwbuffer->data_len = allxfer_len;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * push inbound doorbell, tell iop driver data write ok
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * await reply on next hwinterrupt for next Qbuffer post
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_iop_message_wrote(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (acb->wqbuf_firstidx == acb->wqbuf_lastidx)
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hba_doorbell_isr(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson uint32_t outbound_doorbell;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson phbamu = (struct HBA_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /*
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * Maybe here we need to check wrqbuffer_lock is locked or not
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * DOORBELL: ding! dong!
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson * check if there are any mail need to pack from firmware
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson outbound_doorbell = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &phbamu->outbound_doorbell);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson /* clear doorbell interrupt */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson &phbamu->outbound_doorbell, outbound_doorbell);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK)
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_iop2drv_data_wrote_handle(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK)
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_iop2drv_data_read_handle(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hbc_doorbell_isr(struct ACB *acb)
ed632624009d91d344479bf05ec24b9e0772939bColin Yi{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson uint32_t outbound_doorbell;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * Maybe here we need to check wrqbuffer_lock is locked or not
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * DOORBELL: ding! dong!
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * check if there are any mail need to pick from firmware
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson outbound_doorbell = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_doorbell);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_doorbell_clear,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_doorbell); /* clear interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_iop2drv_data_wrote_handle(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson arcmsr_iop2drv_data_read_handle(acb);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* messenger of "driver to iop commands" */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_hbc_message_isr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hba_message_isr(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t *signature = (&phbamu->msgcode_rwbuffer[0]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t outbound_message;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intstatus, ARCMSR_MU_OUTBOUND_MESSAGE0_INT);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_message = CHIP_REG_READ32(acb->reg_mu_acc_handle0, signature);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((ddi_taskq_dispatch(acb->taskq,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void (*)(void *))arcmsr_dr_handle,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb, DDI_NOSLEEP)) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "DR task start failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hbb_message_isr(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t *signature = (&phbbmu->hbb_rwbuffer->msgcode_rwbuffer[0]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t outbound_message;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DRV2IOP_END_OF_INTERRUPT);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_message = CHIP_REG_READ32(acb->reg_mu_acc_handle0, signature);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((ddi_taskq_dispatch(acb->taskq,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void (*)(void *))arcmsr_dr_handle,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb, DDI_NOSLEEP)) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "DR task start failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hbc_message_isr(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t *signature = (&phbcmu->msgcode_rwbuffer[0]);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t outbound_message;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_doorbell_clear,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_message = CHIP_REG_READ32(acb->reg_mu_acc_handle0, signature);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if ((ddi_taskq_dispatch(acb->taskq,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void (*)(void *))arcmsr_dr_handle,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb, DDI_NOSLEEP)) != DDI_SUCCESS) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "DR task start failed");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPhersonstatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hba_postqueue_isr(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t flag_ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore boolean_t error;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* areca cdb command done */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Use correct offset and size for syncing */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_sync(acb->ccbs_pool_handle, 0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SYNC_FORKERNEL);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while ((flag_ccb = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_queueport)) != 0xFFFFFFFF) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* frame must be 32 bytes aligned */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = NumToPtr((acb->vir2phy_offset+(flag_ccb << 5)));
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check if command done with no error */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore B_TRUE : B_FALSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_drain_donequeue(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } /* drain reply FIFO */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hbb_postqueue_isr(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t flag_ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore boolean_t error;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore int index;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* areca cdb command done */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore index = phbbmu->doneq_index;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (ddi_dma_sync(acb->ccbs_pool_handle, 0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SYNC_FORKERNEL) != DDI_SUCCESS)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while ((flag_ccb = phbbmu->done_qbuffer[index]) != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->done_qbuffer[index] = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* frame must be 32 bytes aligned */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* the CDB is the first field of the CCB */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = NumToPtr((acb->vir2phy_offset + (flag_ccb << 5)));
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check if command done with no error */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore B_TRUE : B_FALSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_drain_donequeue(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore index++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* if last index number set it to 0 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore index %= ARCMSR_MAX_HBB_POSTQUEUE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->doneq_index = index;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } /* drain reply FIFO */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_hbc_postqueue_isr(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t flag_ccb, ccb_cdb_phy, throttling = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore boolean_t error;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* areca cdb command done */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* Use correct offset and size for syncing */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) ddi_dma_sync(acb->ccbs_pool_handle, 0, 0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore DDI_DMA_SYNC_FORKERNEL);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while (CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->host_int_status) &
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check if command done with no error */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore flag_ccb = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_queueport_low);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* frame must be 32 bytes aligned */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* the CDB is the first field of the CCB */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ccb = NumToPtr((acb->vir2phy_offset + ccb_cdb_phy));
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ?
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore B_TRUE : B_FALSE;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check if command done with no error */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_drain_donequeue(acb, ccb, error);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore throttling++;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } /* drain reply FIFO */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_handle_hba_isr(struct ACB *acb) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t outbound_intstatus;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_intstatus = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_intstatus) & acb->outbound_int_enable;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_intstatus == 0) /* it must be a shared irq */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_INTR_UNCLAIMED);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbamu->outbound_intstatus,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_intstatus); /* clear interrupt */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* MU doorbell interrupts */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_hba_doorbell_isr(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* MU post queue interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_hba_postqueue_isr(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_intstatus & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_hba_message_isr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_INTR_CLAIMED);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_handle_hbb_isr(struct ACB *acb) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t outbound_doorbell;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_doorbell = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell) & acb->outbound_int_enable;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_doorbell == 0) /* it must be a shared irq */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_INTR_UNCLAIMED);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear doorbell interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell, ~outbound_doorbell);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* wait a cycle */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DRV2IOP_END_OF_INTERRUPT);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* MU ioctl transfer doorbell interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop2drv_data_wrote_handle(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_READ_OK)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_iop2drv_data_read_handle(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* MU post queue interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_doorbell & ARCMSR_IOP2DRV_CDB_DONE)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_hbb_postqueue_isr(acb);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* MU message interrupt */
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (outbound_doorbell & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_hbb_message_isr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_INTR_CLAIMED);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_handle_hbc_isr(struct ACB *acb)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t host_interrupt_status;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* check outbound intstatus */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore host_interrupt_status=
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ32(acb->reg_mu_acc_handle0, &phbcmu->host_int_status);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (host_interrupt_status == 0) /* it must be share irq */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_INTR_UNCLAIMED);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* MU ioctl transfer doorbell interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* messenger of "ioctl message read write" */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_hbc_doorbell_isr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* MU post queue interrupts */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* messenger of "scsi commands" */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_hbc_postqueue_isr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (DDI_INTR_CLAIMED);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_intr_handler(caddr_t arg, caddr_t arg2)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct ACB *acb = (void *)arg;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct CCB *ccb;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint_t retrn = DDI_INTR_UNCLAIMED;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore _NOTE(ARGUNUSED(arg2))
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_enter(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retrn = arcmsr_handle_hba_isr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retrn = arcmsr_handle_hbb_isr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore retrn = arcmsr_handle_hbc_isr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore default:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* We should never be here */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ASSERT(0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore mutex_exit(&acb->isr_mutex);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore while ((ccb = arcmsr_get_complete_ccb_from_list(acb)) != NULL) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_ccb_complete(ccb, 1);
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (retrn);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore}
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_wait_firmware_ready(struct ACB *acb) {
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t firmware_state;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore firmware_state = 0;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore do {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore firmware_state =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_msgaddr1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } while ((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore == 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore do {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore firmware_state =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DRV2IOP_END_OF_INTERRUPT);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore do {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore firmware_state =
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_msgaddr1);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore } while ((firmware_state & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore == 0);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
508aff1a85ed04f187fd074799bcaefd630490f1James C. McPherson}
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_clear_doorbell_queue_buffer(struct ACB *acb)
ed632624009d91d344479bf05ec24b9e0772939bColin Yi{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A: {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t outbound_doorbell;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* empty doorbell Qbuffer if door bell rung */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_doorbell = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_doorbell);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear doorbell interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->outbound_doorbell, outbound_doorbell);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B: {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear interrupt and message state */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->iop2drv_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_DRV2IOP_DATA_READ_OK);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* let IOP know data has been read */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C: {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t outbound_doorbell;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* empty doorbell Qbuffer if door bell ringed */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore outbound_doorbell = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_doorbell);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* clear outbound doobell isr */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->outbound_doorbell_clear, outbound_doorbell);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* let IOP know data has been read */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
ed632624009d91d344479bf05ec24b9e0772939bColin Yi}
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic uint32_t
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_iop_confirm(struct ACB *acb) {
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint64_t cdb_phyaddr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t cdb_phyaddr_hi32;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * here we need to tell iop 331 about our freeccb.HighPart
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * if freeccb.HighPart is non-zero
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_phyaddr = acb->ccb_cookie.dmac_laddress;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_phyaddr_hi32 = (uint32_t)((cdb_phyaddr >> 16) >> 16);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->cdb_phyaddr_hi32 = cdb_phyaddr_hi32;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (cdb_phyaddr_hi32 != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBA_msgUnit *phbamu;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbamu = (struct HBA_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->msgcode_rwbuffer[0],
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_SIGNATURE_SET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->msgcode_rwbuffer[1], cdb_phyaddr_hi32);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbamu->inbound_msgaddr0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_MESG0_SET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hba_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout setting ccb "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "high physical address");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (FALSE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* if adapter is type B, set window of "post command queue" */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B: {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t post_queue_phyaddr;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->postq_index = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu->doneq_index = 0;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_SET_POST_WINDOW);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbb_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "timeout setting post command "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "queue window");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (FALSE);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore post_queue_phyaddr = (uint32_t)cdb_phyaddr +
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MAX_FREECCB_NUM * P2ROUNDUP(sizeof (struct CCB), 32)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore + offsetof(struct HBB_msgUnit, post_qbuffer);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* driver "set config" signature */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[0],
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_SIGNATURE_SET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* normal should be zero */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[1],
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore cdb_phyaddr_hi32);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* postQ size (256+8)*4 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[2],
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore post_queue_phyaddr);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* doneQ size (256+8)*4 */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[3],
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore post_queue_phyaddr+1056);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* ccb maxQ size must be --> [(256+8)*4] */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle1,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[4], 1056);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_SET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbb_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "timeout setting command queue window");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (FALSE);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_START_DRIVER_MODE);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbb_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "timeout in 'start driver mode'");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (FALSE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (cdb_phyaddr_hi32 != 0) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBC_msgUnit *phbcmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbcmu = (struct HBC_msgUnit *)acb->pmu;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->msgcode_rwbuffer[0],
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_SIGNATURE_SET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->msgcode_rwbuffer[1], cdb_phyaddr_hi32);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_msgaddr0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_INBOUND_MESG0_SET_CONFIG);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbcmu->inbound_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbc_wait_msgint_ready(acb)) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "'set ccb "
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore "high part physical address' timeout");
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (FALSE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore return (TRUE);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi}
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/*
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore * ONLY used for Adapter type B
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_enable_eoi_mode(struct ACB *acb)
ed632624009d91d344479bf05ec24b9e0772939bColin Yi{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore struct HBB_msgUnit *phbbmu;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore phbbmu = (struct HBB_msgUnit *)acb->pmu;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore &phbbmu->hbb_doorbell->drv2iop_doorbell,
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore ARCMSR_MESSAGE_ACTIVE_EOI_MODE);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (!arcmsr_hbb_wait_msgint_ready(acb))
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_warn(acb, "'iop enable eoi mode' timeout");
ed632624009d91d344479bf05ec24b9e0772939bColin Yi}
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore/* start background rebuild */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorestatic void
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amorearcmsr_iop_init(struct ACB *acb)
ed632624009d91d344479bf05ec24b9e0772939bColin Yi{
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore uint32_t intmask_org;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* disable all outbound interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore intmask_org = arcmsr_disable_allintr(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_wait_firmware_ready(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore (void) arcmsr_iop_confirm(acb);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* start background rebuild */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore switch (acb->adapter_type) {
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_A:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_get_hba_config(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_start_hba_bgrb(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_B:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_get_hbb_config(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_start_hbb_bgrb(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore break;
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore case ACB_ADAPTER_TYPE_C:
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_get_hbc_config(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_start_hbc_bgrb(acb);
ed632624009d91d344479bf05ec24b9e0772939bColin Yi break;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi }
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* empty doorbell Qbuffer if door bell rang */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_clear_doorbell_queue_buffer(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore if (acb->adapter_type == ACB_ADAPTER_TYPE_B)
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_eoi_mode(acb);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore /* enable outbound Post Queue, outbound doorbell Interrupt */
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore arcmsr_enable_allintr(acb, intmask_org);
82beb6028da8d7d7f8562908ca027bd4a1cc7d37Garrett D'Amore acb->acb_flags |= ACB_F_IOP_INITED;
ed632624009d91d344479bf05ec24b9e0772939bColin Yi}