507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * CDDL HEADER START
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The contents of this file are subject to the terms of the
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Common Development and Distribution License (the "License").
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * You may not use this file except in compliance with the License.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * or http://www.opensolaris.org/os/licensing.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * See the License for the specific language governing permissions
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and limitations under the License.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * When distributing Covered Code, include this CDDL HEADER in each
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If applicable, add the following below this CDDL HEADER, with the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * fields enclosed by brackets "[]" replaced with your own identifying
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * information: Portions Copyright [yyyy] [name of copyright owner]
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * CDDL HEADER END
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
0f1b305ee9e700c825d9e9ad1ea1e4311d212eb2Seth Goldberg * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Use is subject to license terms.
89b43686db1fe9681d80a7cf5662730cb9378caeBayard Bell * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#include <sys/types.h>
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#include "ata_common.h"
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#include "atapi.h"
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* SCSA entry points */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int atapi_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int atapi_tran_tgt_probe(struct scsi_device *sd, int (*callback)(void));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void atapi_tran_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int atapi_tran_abort(struct scsi_address *ap, struct scsi_pkt *spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int atapi_tran_reset(struct scsi_address *ap, int level);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int atapi_tran_getcap(struct scsi_address *ap, char *capstr, int whom);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int atapi_tran_setcap(struct scsi_address *ap, char *capstr,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int value, int whom);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic struct scsi_pkt *atapi_tran_init_pkt(struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *spktp, struct buf *bp, int cmdlen, int statuslen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int tgtlen, int flags, int (*callback)(caddr_t), caddr_t arg);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void atapi_tran_destroy_pkt(struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void atapi_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void atapi_tran_sync_pkt(struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int atapi_tran_start(struct scsi_address *ap, struct scsi_pkt *spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * packet callbacks
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void atapi_complete(ata_drv_t *ata_drvp, ata_pkt_t *ata_pktp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int do_callback);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int atapi_id_update(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pkt_t *ata_pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Local static data
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#if 0
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic ddi_dma_lim_t atapi_dma_limits = {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 0, /* address low */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 0xffffffffU, /* address high */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 0, /* counter max */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 1, /* burstsize */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf DMA_UNIT_8, /* minimum xfer */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 0, /* dma speed */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf (uint_t)DMALIM_VER0, /* version */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 0xffffffffU, /* address register */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 0xffffffffU, /* counter register */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 1, /* granular */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 1, /* scatter/gather list length */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 0xffffffffU /* request size */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf};
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#endif
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int atapi_use_static_geometry = TRUE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int atapi_arq_enable = TRUE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Call SCSA init to initialize the ATAPI half of the driver
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfint
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_attach(ata_ctl_t *ata_ctlp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf dev_info_t *dip = ata_ctlp->ac_dip;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_hba_tran_t *tran;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_init entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* allocate transport structure */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (tran == NULL) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_WARN(("atapi_init: scsi_hba_tran_alloc failed\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf goto errout;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp->ac_atapi_tran = tran;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp->ac_flags |= AC_SCSI_HBA_TRAN_ALLOC;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* initialize transport structure */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_hba_private = ata_ctlp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_tgt_private = NULL;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_tgt_init = atapi_tran_tgt_init;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_tgt_probe = atapi_tran_tgt_probe;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_tgt_free = atapi_tran_tgt_free;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_start = atapi_tran_start;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_reset = atapi_tran_reset;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_abort = atapi_tran_abort;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_getcap = atapi_tran_getcap;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_setcap = atapi_tran_setcap;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_init_pkt = atapi_tran_init_pkt;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_destroy_pkt = atapi_tran_destroy_pkt;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_dmafree = atapi_tran_dmafree;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tran->tran_sync_pkt = atapi_tran_sync_pkt;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (scsi_hba_attach_setup(ata_ctlp->ac_dip, &ata_pciide_dma_attr, tran,
6fd12ef379fdceac740caa2565388cb7d7aee547lh SCSI_HBA_TRAN_CLONE) != DDI_SUCCESS) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_WARN(("atapi_init: scsi_hba_attach_setup failed\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf goto errout;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp->ac_flags |= AC_SCSI_HBA_ATTACH;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (TRUE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlferrout:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf atapi_detach(ata_ctlp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (FALSE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * destroy the atapi sub-system
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfvoid
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_detach(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctl_t *ata_ctlp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_detach entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_ctlp->ac_flags & AC_SCSI_HBA_ATTACH)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj (void) scsi_hba_detach(ata_ctlp->ac_dip);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_ctlp->ac_flags & AC_SCSI_HBA_TRAN_ALLOC)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_hba_tran_free(ata_ctlp->ac_atapi_tran);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * initialize the ATAPI drive's soft-state based on the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * response to IDENTIFY PACKET DEVICE command
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfint
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_init_drive(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drv_t *ata_drvp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
c8531848467a8747b65b91ab83c4b57f4c000848yt ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
c8531848467a8747b65b91ab83c4b57f4c000848yt
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_init_drive entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Determine ATAPI CDB size */
62c8caf3fac65817982e780c1efa988846153bf0Ada (void) atapi_id_update(ata_ctlp, ata_drvp, NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf switch (ata_drvp->ad_id.ai_config & ATAPI_ID_CFG_PKT_SZ) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case ATAPI_ID_CFG_PKT_12B:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drvp->ad_cdb_len = 12;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf break;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case ATAPI_ID_CFG_PKT_16B:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drvp->ad_cdb_len = 16;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf break;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf default:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_WARN(("atapi_init_drive: bad pkt size support\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (FALSE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* determine if drive gives an intr when it wants the CDB */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if ((ata_drvp->ad_id.ai_config & ATAPI_ID_CFG_DRQ_TYPE) !=
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ATAPI_ID_CFG_DRQ_INTR)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drvp->ad_flags |= AD_NO_CDB_INTR;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
c8531848467a8747b65b91ab83c4b57f4c000848yt /*
c8531848467a8747b65b91ab83c4b57f4c000848yt * Some devices may have no DMA mode enabled (UDMA or MWDMA)
c8531848467a8747b65b91ab83c4b57f4c000848yt * by default, so here we need check and enable DMA if none
c8531848467a8747b65b91ab83c4b57f4c000848yt * mode is selected.
c8531848467a8747b65b91ab83c4b57f4c000848yt */
c8531848467a8747b65b91ab83c4b57f4c000848yt if (ata_set_dma_mode(ata_ctlp, ata_drvp) == TRUE) {
c8531848467a8747b65b91ab83c4b57f4c000848yt /* Update the IDENTIFY PACKET DEVICE data */
c8531848467a8747b65b91ab83c4b57f4c000848yt (void) atapi_id_update(ata_ctlp, ata_drvp, NULL);
c8531848467a8747b65b91ab83c4b57f4c000848yt }
c8531848467a8747b65b91ab83c4b57f4c000848yt
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (TRUE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * destroy an atapi drive
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfvoid
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_uninit_drive(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drv_t *ata_drvp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_uninit_drive entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Issue an IDENTIFY PACKET (ATAPI) DEVICE command
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfint
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_id(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_acc_handle_t io_hdl1,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf caddr_t ioaddr1,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_acc_handle_t io_hdl2,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf caddr_t ioaddr2,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct ata_id *ata_idp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int rc;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_id entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = ata_id_common(ATC_ID_PACKET_DEVICE, FALSE, io_hdl1, ioaddr1,
6fd12ef379fdceac740caa2565388cb7d7aee547lh io_hdl2, ioaddr2, ata_idp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!rc)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (FALSE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if ((ata_idp->ai_config & ATAC_ATAPI_TYPE_MASK) != ATAC_ATAPI_TYPE)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (FALSE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (TRUE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Check the device's register block for the ATAPI signature.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Although the spec says the sector count, sector number and device/head
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * registers are also part of the signature, for some unknown reason, this
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * routine only checks the cyl hi and cyl low registers. I'm just
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * guessing, but it might be because ATA and ATAPI devices return
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * identical values in those registers and we actually rely on the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * IDENTIFY DEVICE and IDENTIFY PACKET DEVICE commands to recognize the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * device type.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfint
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_signature(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_acc_handle_t io_hdl,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf caddr_t ioaddr)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int rc = FALSE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_signature entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ddi_get8(io_hdl, (uchar_t *)ioaddr + AT_HCYL) == ATAPI_SIG_HI &&
6fd12ef379fdceac740caa2565388cb7d7aee547lh ddi_get8(io_hdl, (uchar_t *)ioaddr + AT_LCYL) != ATAPI_SIG_LO)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = TRUE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The following is a little bit of bullet proofing.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * When some drives are configured on a master-only bus they
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * "shadow" their registers for the not-present slave drive.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * This is bogus and if you're not careful it may cause a
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * master-only drive to be mistakenly recognized as both
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * master and slave. By clearing the signature registers here
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * I can make certain that when ata_drive_type() switches from
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the master to slave drive that I'll read back non-signature
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * values regardless of whether the master-only drive does
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the "shadow" register trick. This prevents a bogus
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * IDENTIFY PACKET DEVICE command from being issued which
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * a really bogus master-only drive will return "shadow"
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * data for.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_put8(io_hdl, (uchar_t *)ioaddr + AT_HCYL, 0);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_put8(io_hdl, (uchar_t *)ioaddr + AT_LCYL, 0);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (rc);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_tgt_init entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_tgt_init(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf dev_info_t *hba_dip,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf dev_info_t *tgt_dip,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_hba_tran_t *hba_tran,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_device *sd)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gtgt_t *gtgtp; /* GHD's per-target-instance structure */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctl_t *ata_ctlp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_tgt_t *ata_tgtp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drv_t *ata_drvp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int rc = DDI_SUCCESS;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_tgt_init entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Qualification of targ, lun, and ATAPI device presence
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * have already been taken care of by ata_bus_ctl
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* store pointer to drive struct in cloned tran struct */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp = TRAN2CTL(hba_tran);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ap = &sd->sd_address;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drvp = CTL2DRV(ata_ctlp, ap->a_target, ap->a_lun);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Create the "atapi" property so the target driver knows
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * to use the correct set of SCSI commands
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!ata_prop_create(tgt_dip, ata_drvp, "atapi")) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (DDI_FAILURE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gtgtp = ghd_target_init(hba_dip, tgt_dip, &ata_ctlp->ac_ccc,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf sizeof (ata_tgt_t), ata_ctlp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ap->a_target, ap->a_lun);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* tran_tgt_private points to gtgt_t */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf hba_tran->tran_tgt_private = gtgtp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* gt_tgt_private points to ata_tgt_t */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_tgtp = GTGTP2ATATGTP(gtgtp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* initialize the per-target-instance data */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_tgtp->at_drvp = ata_drvp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_tgtp->at_dma_attr = ata_pciide_dma_attr;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_tgtp->at_dma_attr.dma_attr_maxxfer =
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp->ac_max_transfer << SCTRSHFT;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (rc);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_tgt_probe entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_tgt_probe(struct scsi_device *sd, int (*callback)(void))
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_tgt_probe entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (scsi_hba_probe(sd, callback));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_tgt_free entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_tgt_free(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf dev_info_t *hba_dip,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf dev_info_t *tgt_dip,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_hba_tran_t *hba_tran,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_device *sd)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_tgt_free entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ghd_target_free(hba_dip, tgt_dip, &TRAN2ATAP(hba_tran)->ac_ccc,
6fd12ef379fdceac740caa2565388cb7d7aee547lh TRAN2GTGTP(hba_tran));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf hba_tran->tran_tgt_private = NULL;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_abort entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_abort(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *spktp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_abort entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (spktp) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (ghd_tran_abort(&ADDR2CTL(ap)->ac_ccc, PKTP2GCMDP(spktp),
6fd12ef379fdceac740caa2565388cb7d7aee547lh ADDR2GTGTP(ap), NULL));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (ghd_tran_abort_lun(&ADDR2CTL(ap)->ac_ccc, ADDR2GTGTP(ap),
6fd12ef379fdceac740caa2565388cb7d7aee547lh NULL));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_reset entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_reset(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int level)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_reset entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (level == RESET_TARGET)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (ghd_tran_reset_target(&ADDR2CTL(ap)->ac_ccc,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADDR2GTGTP(ap), NULL));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (level == RESET_ALL)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (ghd_tran_reset_bus(&ADDR2CTL(ap)->ac_ccc,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADDR2GTGTP(ap), NULL));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (FALSE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_setcap entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_setcap(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf char *capstr,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int value,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int whom)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gtgt_t *gtgtp = ADDR2GTGTP(ap);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_tgt_t *tgtp = GTGTP2ATATGTP(gtgtp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_setcap entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf switch (scsi_hba_lookup_capstr(capstr)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case SCSI_CAP_SECTOR_SIZE:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tgtp->at_dma_attr.dma_attr_granular = (uint_t)value;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (TRUE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case SCSI_CAP_ARQ:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (whom) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tgtp->at_arq = value;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (TRUE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf break;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case SCSI_CAP_TOTAL_SECTORS:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tgtp->at_total_sectors = value;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (TRUE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (FALSE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_getcap entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_getcap(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf char *capstr,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int whom)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct ata_id ata_id;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct ata_id *ata_idp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctl_t *ata_ctlp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drv_t *ata_drvp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gtgt_t *gtgtp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int rval = -1;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_getcap entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (capstr == NULL || whom == 0)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (-1);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp = ADDR2CTL(ap);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf switch (scsi_hba_lookup_capstr(capstr)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case SCSI_CAP_ARQ:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rval = TRUE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf break;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case SCSI_CAP_INITIATOR_ID:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rval = 7;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf break;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case SCSI_CAP_DMA_MAX:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* XXX - what should the real limit be?? */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* limit to 64K ??? */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rval = 4096 * (ATA_DMA_NSEGS - 1);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf break;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case SCSI_CAP_GEOMETRY:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Default geometry */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (atapi_use_static_geometry) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rval = ATAPI_HEADS << 16 | ATAPI_SECTORS_PER_TRK;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf break;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* this code is currently not used */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drvp = CTL2DRV(ata_ctlp, ap->a_target, ap->a_lun);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gtgtp = ADDR2GTGTP(ap);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * retrieve the current IDENTIFY PACKET DEVICE info
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!ata_queue_cmd(atapi_id_update, &ata_id, ata_ctlp,
6fd12ef379fdceac740caa2565388cb7d7aee547lh ata_drvp, gtgtp)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_getcap geometry failed"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (0);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * save the new response data
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_idp = &ata_drvp->ad_id;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *ata_idp = ata_id;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf switch ((ata_idp->ai_config >> 8) & 0xf) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case DTYPE_RODIRECT:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rval = ATAPI_HEADS << 16 | ATAPI_SECTORS_PER_TRK;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf break;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case DTYPE_DIRECT:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case DTYPE_OPTICAL:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rval = (ata_idp->ai_curheads << 16) |
6fd12ef379fdceac740caa2565388cb7d7aee547lh ata_idp->ai_cursectrk;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf break;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf default:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rval = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf break;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (rval);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_init_pkt entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic struct scsi_pkt *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_init_pkt(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *spktp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct buf *bp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int cmdlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int statuslen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int tgtlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int flags,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int (*callback)(caddr_t),
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf caddr_t arg)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gtgt_t *gtgtp = ADDR2GTGTP(ap);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_tgt_t *ata_tgtp = GTGTP2ATATGTP(gtgtp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctl_t *ata_ctlp = ADDR2CTL(ap);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pkt_t *ata_pktp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *new_spktp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_dma_attr_t *sg_attrp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int bytes;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_init_pkt entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Determine whether to do PCI-IDE DMA setup, start out by
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * assuming we're not.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf sg_attrp = NULL;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (bp == NULL) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* no data to transfer */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf goto skip_dma_setup;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (bp->b_bcount == 0) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* no data to transfer */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf goto skip_dma_setup;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if ((GTGTP2ATADRVP(ADDR2GTGTP(ap))->ad_pciide_dma == ATA_DMA_OFF)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf goto skip_dma_setup;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_dma_disabled)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf goto skip_dma_setup;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The PCI-IDE DMA engine is brain-damaged and can't
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * DMA non-aligned buffers.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (((bp->b_flags & B_PAGEIO) == 0) &&
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ((uintptr_t)bp->b_un.b_addr) & PCIIDE_PRDE_ADDR_MASK) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * if the virtual address isn't aligned, then the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * physical address also isn't aligned.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf goto skip_dma_setup;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * It also insists that the byte count must be even.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (bp->b_bcount & 1) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* something odd here */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf goto skip_dma_setup;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Huzza! We're really going to do it
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf sg_attrp = &ata_tgtp->at_dma_attr;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfskip_dma_setup:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Call GHD packet init function
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf new_spktp = ghd_tran_init_pkt_attr(&ata_ctlp->ac_ccc, ap, spktp, bp,
6fd12ef379fdceac740caa2565388cb7d7aee547lh cmdlen, statuslen, tgtlen, flags,
6fd12ef379fdceac740caa2565388cb7d7aee547lh callback, arg, sizeof (ata_pkt_t), sg_attrp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (new_spktp == NULL)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp = SPKT2APKT(new_spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_cdbp = new_spktp->pkt_cdbp;
6fd12ef379fdceac740caa2565388cb7d7aee547lh if (statuslen > 255) {
6fd12ef379fdceac740caa2565388cb7d7aee547lh statuslen = sizeof (struct scsi_arq_status);
6fd12ef379fdceac740caa2565388cb7d7aee547lh }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_statuslen = (uchar_t)statuslen;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* reset data direction flags */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (spktp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_flags &= ~(AP_READ | AP_WRITE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * check for ARQ mode
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (atapi_arq_enable == TRUE &&
6fd12ef379fdceac740caa2565388cb7d7aee547lh ata_tgtp->at_arq == TRUE &&
6fd12ef379fdceac740caa2565388cb7d7aee547lh ata_pktp->ap_statuslen >= sizeof (struct scsi_arq_status)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_init_pkt ARQ\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_scbp =
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf (struct scsi_arq_status *)new_spktp->pkt_scbp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_flags |= AP_ARQ_ON_ERROR;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * fill these with zeros for ATA/ATAPI-4 compatibility
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_sec = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_count = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_pktp->ap_sg_cnt) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ASSERT(bp != NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* determine direction to program the DMA engine later */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (bp->b_flags & B_READ) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_flags |= AP_READ;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_flags |= AP_WRITE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_pciide_dma = TRUE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_hicyl = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_lwcyl = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (new_spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Since we're not using DMA, we need to map the buffer into
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * kernel address space
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_pciide_dma = FALSE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (bp && bp->b_bcount) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If this is a fresh request map the buffer and
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * reset the ap_baddr pointer and the current offset
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and byte count.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The ap_boffset is used to set the ap_v_addr ptr at
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the start of each I/O request.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The ap_bcount is used to update ap_boffset when the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * target driver requests the next segment.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (cmdlen) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf bp_mapin(bp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_baddr = bp->b_un.b_addr;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_bcount = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_boffset = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ASSERT(ata_pktp->ap_baddr != NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* determine direction for the PIO FSM */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (bp->b_flags & B_READ) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_flags |= AP_READ;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_flags |= AP_WRITE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If the drive has the Single Sector bug, limit
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the transfer to a single sector. This assumes
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * ATAPI CD drives always use 2k sectors.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (GTGTP2ATADRVP(ADDR2GTGTP(ap))->ad_flags & AD_1SECTOR) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf size_t resid;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf size_t tmp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* adjust offset based on prior request */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_boffset += ata_pktp->ap_bcount;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* compute number of bytes left to transfer */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf resid = bp->b_bcount - ata_pktp->ap_boffset;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* limit the transfer to 2k */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tmp = MIN(2048, resid);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_bcount = tmp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* tell target driver how much is left for next time */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf new_spktp->pkt_resid = resid - tmp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* do the whole request in one swell foop */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_bcount = bp->b_bcount;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf new_spktp->pkt_resid = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_baddr = NULL;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_bcount = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_boffset = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * determine the size of each partial data transfer
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * to/from the drive
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf bytes = min(ata_pktp->ap_bcount, ATAPI_MAX_BYTES_PER_DRQ);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_hicyl = (uchar_t)(bytes >> 8);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_lwcyl = (uchar_t)bytes;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (new_spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * GHD ccballoc callback
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Initializing the ata_pkt, and return the ptr to the gcmd_t to GHD.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfint
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_ccballoc(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gtgt_t *gtgtp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmd_t *gcmdp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int cmdlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int statuslen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int tgtlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int ccblen)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drv_t *ata_drvp = GTGTP2ATADRVP(gtgtp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pkt_t *ata_pktp = GCMD2APKT(gcmdp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_ccballoc entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* set the back ptr from the ata_pkt to the gcmd_t */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_gcmdp = gcmdp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* check length of SCSI CDB is not larger than drive expects */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (cmdlen > ata_drvp->ad_cdb_len) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_WARN(("atapi_ccballoc: SCSI CDB too large!\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (FALSE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * save length of the SCSI CDB, and calculate CDB padding
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * note that for convenience, padding is expressed in shorts.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_cdb_len = (uchar_t)cmdlen;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_cdb_pad =
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ((unsigned)(ata_drvp->ad_cdb_len - cmdlen)) >> 1;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* set up callback functions */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_start = atapi_fsm_start;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_intr = atapi_fsm_intr;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_complete = atapi_complete;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* set-up for start */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_flags = AP_ATAPI;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_hd = ata_drvp->ad_drive_bits;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_cmd = ATC_PACKET;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (TRUE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_destroy_pkt entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_destroy_pkt(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *spktp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmd_t *gcmdp = PKTP2GCMDP(spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_destroy_pkt entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (gcmdp->cmd_dma_handle != NULL) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ghd_dmafree_attr(gcmdp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ghd_pktfree(&ADDR2CTL(ap)->ac_ccc, ap, spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * GHD ccbfree callback function
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfvoid
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_ccbfree(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmd_t *gcmdp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_ccbfree entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* nothing to do */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_dmafree entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*ARGSUSED*/
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_dmafree(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *spktp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmd_t *gcmdp = PKTP2GCMDP(spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_dmafree entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (gcmdp->cmd_dma_handle != NULL) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ghd_dmafree_attr(gcmdp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_sync_pkt entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*ARGSUSED*/
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_sync_pkt(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *spktp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_sync_pkt entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (PKTP2GCMDP(spktp)->cmd_dma_handle != NULL) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ghd_tran_sync_pkt(ap, spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA tran_start entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_tran_start(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *spktp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pkt_t *ata_pktp = SPKT2APKT(spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drv_t *ata_drvp = APKT2DRV(ata_pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmd_t *gcmdp = APKT2GCMD(ata_pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int polled = FALSE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int rc;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_tran_start entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Basic initialization performed each and every time a
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * scsi_pkt is submitted. A single scsi_pkt may be submitted
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * multiple times so this routine has to be idempotent. One
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * time initializations don't belong here.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The ap_v_addr pointer is incremented by the PIO data
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * transfer routine as each word is transferred. Therefore, need
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * to reset ap_v_addr here (rather than atapi_tran_init_pkt())
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * in case the target resubmits the same pkt multiple times
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * (which is permitted by SCSA).
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_v_addr = ata_pktp->ap_baddr + ata_pktp->ap_boffset;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* ap_resid is decremented as the data transfer progresses */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_resid = ata_pktp->ap_bcount;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* clear error flags */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_flags &= (AP_ATAPI | AP_READ | AP_WRITE | AP_ARQ_ON_ERROR);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_reason = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_state = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_statistics = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * check for polling pkt
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (spktp->pkt_flags & FLAG_NOINTR) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf polled = TRUE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#ifdef ___just_ignore_unsupported_flags___
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* driver cannot accept tagged commands */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (spktp->pkt_flags & (FLAG_HTAG|FLAG_OTAG|FLAG_STAG)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_reason = CMD_TRAN_ERR;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (TRAN_BADPKT);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#endif
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* call common transport routine */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = ghd_transport(&ata_ctlp->ac_ccc, gcmdp, gcmdp->cmd_gtgtp,
6fd12ef379fdceac740caa2565388cb7d7aee547lh spktp->pkt_time, polled, NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* see if pkt was not accepted */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (rc != TRAN_ACCEPT)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (rc);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (rc);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * GHD packet complete callback
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_complete(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drv_t *ata_drvp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pkt_t *ata_pktp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int do_callback)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *spktp = APKT2SPKT(ata_pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_status *scsi_stat = (struct scsi_status *)spktp->pkt_scbp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("atapi_complete entered\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRANSPORT(("atapi_complete: pkt = 0x%p\n", ata_pktp));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* update resid */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_resid = ata_pktp->ap_resid;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_pktp->ap_flags & AP_SENT_CMD) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_state |=
6fd12ef379fdceac740caa2565388cb7d7aee547lh STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_pktp->ap_flags & AP_XFERRED_DATA) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_state |= STATE_XFERRED_DATA;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_pktp->ap_flags & AP_GOT_STATUS) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_state |= STATE_GOT_STATUS;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* check for fatal errors */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_pktp->ap_flags & AP_TRAN_ERROR) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_reason = CMD_TRAN_ERR;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else if (ata_pktp->ap_flags & AP_BUS_RESET) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_reason = CMD_RESET;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_statistics |= STAT_BUS_RESET;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else if (ata_pktp->ap_flags & AP_DEV_RESET) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_reason = CMD_RESET;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_statistics |= STAT_DEV_RESET;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else if (ata_pktp->ap_flags & AP_ABORT) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_reason = CMD_ABORTED;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_statistics |= STAT_ABORTED;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else if (ata_pktp->ap_flags & AP_TIMEOUT) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_reason = CMD_TIMEOUT;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_statistics |= STAT_TIMEOUT;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_reason = CMD_CMPLT;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* non-fatal errors */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_pktp->ap_flags & AP_ERROR)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_stat->sts_chk = 1;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf else
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_stat->sts_chk = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_pktp->ap_flags & AP_ARQ_ERROR) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_ARQ(("atapi_complete ARQ error 0x%p\n", ata_pktp));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_reason = CMD_TRAN_ERR;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else if (ata_pktp->ap_flags & AP_ARQ_OKAY) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf static struct scsi_status zero_scsi_status = { 0 };
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_arq_status *arqp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_ARQ(("atapi_complete ARQ okay 0x%p\n", ata_pktp));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf spktp->pkt_state |= STATE_ARQ_DONE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arqp = ata_pktp->ap_scbp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arqp->sts_rqpkt_reason = CMD_CMPLT;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arqp->sts_rqpkt_state = STATE_XFERRED_DATA;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arqp->sts_rqpkt_status = zero_scsi_status;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arqp->sts_rqpkt_resid = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arqp->sts_rqpkt_statistics = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRANSPORT(("atapi_complete: reason = 0x%x stats = 0x%x "
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "sts_chk = %d\n", spktp->pkt_reason, spktp->pkt_statistics,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_stat->sts_chk));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (do_callback && (spktp->pkt_comp))
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf (*spktp->pkt_comp)(spktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Update the IDENTIFY PACKET DEVICE info
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_id_update(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctl_t *ata_ctlp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_drv_t *ata_drvp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pkt_t *ata_pktp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf caddr_t ioaddr1 = ata_ctlp->ac_ioaddr1;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf caddr_t ioaddr2 = ata_ctlp->ac_ioaddr2;
c8531848467a8747b65b91ab83c4b57f4c000848yt struct ata_id *aidp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int rc;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * select the appropriate drive and LUN
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_put8(io_hdl1, (uchar_t *)ioaddr1 + AT_DRVHD,
6fd12ef379fdceac740caa2565388cb7d7aee547lh ata_drvp->ad_drive_bits);
9f49ae270d37efd5c5270cb8046b4229b5380021mlf ata_nsecwait(400);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * make certain the drive is selected, and wait for not busy
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!ata_wait(io_hdl2, ioaddr2, ATS_DRDY, ATS_BSY, 5 * 1000000)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_ERROR(("atapi_id_update: select failed\n"));
c8531848467a8747b65b91ab83c4b57f4c000848yt if (ata_pktp != NULL)
c8531848467a8747b65b91ab83c4b57f4c000848yt ata_pktp->ap_flags |= AP_ERROR;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (ATA_FSM_RC_FINI);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
c8531848467a8747b65b91ab83c4b57f4c000848yt if (ata_pktp != NULL)
c8531848467a8747b65b91ab83c4b57f4c000848yt aidp = (struct ata_id *)ata_pktp->ap_v_addr;
c8531848467a8747b65b91ab83c4b57f4c000848yt else
c8531848467a8747b65b91ab83c4b57f4c000848yt aidp = &ata_drvp->ad_id;
c8531848467a8747b65b91ab83c4b57f4c000848yt
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = atapi_id(ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1,
c8531848467a8747b65b91ab83c4b57f4c000848yt ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, aidp);
62c8caf3fac65817982e780c1efa988846153bf0Ada if (rc) {
62c8caf3fac65817982e780c1efa988846153bf0Ada swab(aidp->ai_drvser, aidp->ai_drvser,
62c8caf3fac65817982e780c1efa988846153bf0Ada sizeof (aidp->ai_drvser));
62c8caf3fac65817982e780c1efa988846153bf0Ada swab(aidp->ai_fw, aidp->ai_fw,
62c8caf3fac65817982e780c1efa988846153bf0Ada sizeof (aidp->ai_fw));
62c8caf3fac65817982e780c1efa988846153bf0Ada swab(aidp->ai_model, aidp->ai_model,
62c8caf3fac65817982e780c1efa988846153bf0Ada sizeof (aidp->ai_model));
62c8caf3fac65817982e780c1efa988846153bf0Ada }
c8531848467a8747b65b91ab83c4b57f4c000848yt
c8531848467a8747b65b91ab83c4b57f4c000848yt if (ata_pktp == NULL)
c8531848467a8747b65b91ab83c4b57f4c000848yt return (ATA_FSM_RC_FINI);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!rc) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_flags |= AP_ERROR;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_flags |= AP_XFERRED_DATA;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (ATA_FSM_RC_FINI);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Both drives on the controller share a common pkt to do
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * ARQ processing. Therefore the pkt is only partially
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * initialized here. The rest of initialization occurs
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * just before starting the ARQ pkt when an error is
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * detected.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfvoid
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfatapi_init_arq(
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctl_t *ata_ctlp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pkt_t *arq_pktp = ata_ctlp->ac_arq_pktp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arq_pktp->ap_cdbp = ata_ctlp->ac_arq_cdb;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arq_pktp->ap_cdb_len = sizeof (ata_ctlp->ac_arq_cdb);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arq_pktp->ap_start = atapi_fsm_start;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arq_pktp->ap_intr = atapi_fsm_intr;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arq_pktp->ap_complete = atapi_complete;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arq_pktp->ap_flags = AP_ATAPI;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arq_pktp->ap_cmd = ATC_PACKET;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp->ac_arq_cdb[0] = SCMD_REQUEST_SENSE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
8c97a06b88a7f040b7d72941ca32323bb75cfec7Ada
8c97a06b88a7f040b7d72941ca32323bb75cfec7Adavoid
fe072f421ec51952432306add7d50852ad1921b2Adaatapi_reset_dma_mode(ata_drv_t *ata_drvp, int need_wait)
8c97a06b88a7f040b7d72941ca32323bb75cfec7Ada{
8c97a06b88a7f040b7d72941ca32323bb75cfec7Ada ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
8c97a06b88a7f040b7d72941ca32323bb75cfec7Ada
fe072f421ec51952432306add7d50852ad1921b2Ada /*
fe072f421ec51952432306add7d50852ad1921b2Ada * Some very old CD-ROM need to wait 500mS to
fe072f421ec51952432306add7d50852ad1921b2Ada * reset the DMA mode, so after reset the DMA
fe072f421ec51952432306add7d50852ad1921b2Ada * mode when resuming, check whether it was
fe072f421ec51952432306add7d50852ad1921b2Ada * enabled on the device, if not, delay 500mS
fe072f421ec51952432306add7d50852ad1921b2Ada * and reset it again. Then for normal DVD/CD-ROM,
fe072f421ec51952432306add7d50852ad1921b2Ada * no delay will be on resume.
fe072f421ec51952432306add7d50852ad1921b2Ada */
fe072f421ec51952432306add7d50852ad1921b2Ada if (need_wait == TRUE)
fe072f421ec51952432306add7d50852ad1921b2Ada drv_usecwait(5 * 100000);
0f1b305ee9e700c825d9e9ad1ea1e4311d212eb2Seth Goldberg ata_reset_dma_mode(ata_drvp);
8c97a06b88a7f040b7d72941ca32323bb75cfec7Ada (void) atapi_id_update(ata_ctlp, ata_drvp, NULL);
8c97a06b88a7f040b7d72941ca32323bb75cfec7Ada}