11709Smlf /*
21709Smlf * CDDL HEADER START
31709Smlf *
41709Smlf * The contents of this file are subject to the terms of the
53446Smrj * Common Development and Distribution License (the "License").
61709Smlf * You may not use this file except in compliance with the License.
71709Smlf *
81709Smlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91709Smlf * or http://www.opensolaris.org/os/licensing.
101709Smlf * See the License for the specific language governing permissions
111709Smlf * and limitations under the License.
121709Smlf *
131709Smlf * When distributing Covered Code, include this CDDL HEADER in each
141709Smlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151709Smlf * If applicable, add the following below this CDDL HEADER, with the
161709Smlf * fields enclosed by brackets "[]" replaced with your own identifying
171709Smlf * information: Portions Copyright [yyyy] [name of copyright owner]
181709Smlf *
191709Smlf * CDDL HEADER END
201709Smlf */
211709Smlf
221709Smlf /*
238550SSeth.Goldberg@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
241709Smlf * Use is subject to license terms.
251709Smlf */
261709Smlf
271709Smlf
281709Smlf #include <sys/types.h>
291709Smlf
301709Smlf #include "ata_common.h"
311709Smlf #include "atapi.h"
321709Smlf
331709Smlf /* SCSA entry points */
341709Smlf
351709Smlf static int atapi_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
361709Smlf scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
371709Smlf static int atapi_tran_tgt_probe(struct scsi_device *sd, int (*callback)(void));
381709Smlf static void atapi_tran_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
391709Smlf scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
401709Smlf static int atapi_tran_abort(struct scsi_address *ap, struct scsi_pkt *spktp);
411709Smlf static int atapi_tran_reset(struct scsi_address *ap, int level);
421709Smlf static int atapi_tran_getcap(struct scsi_address *ap, char *capstr, int whom);
431709Smlf static int atapi_tran_setcap(struct scsi_address *ap, char *capstr,
441709Smlf int value, int whom);
451709Smlf static struct scsi_pkt *atapi_tran_init_pkt(struct scsi_address *ap,
461709Smlf struct scsi_pkt *spktp, struct buf *bp, int cmdlen, int statuslen,
471709Smlf int tgtlen, int flags, int (*callback)(caddr_t), caddr_t arg);
481709Smlf static void atapi_tran_destroy_pkt(struct scsi_address *ap,
491709Smlf struct scsi_pkt *spktp);
501709Smlf static void atapi_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *spktp);
511709Smlf static void atapi_tran_sync_pkt(struct scsi_address *ap,
521709Smlf struct scsi_pkt *spktp);
531709Smlf static int atapi_tran_start(struct scsi_address *ap, struct scsi_pkt *spktp);
541709Smlf
551709Smlf /*
561709Smlf * packet callbacks
571709Smlf */
581709Smlf static void atapi_complete(ata_drv_t *ata_drvp, ata_pkt_t *ata_pktp,
591709Smlf int do_callback);
601709Smlf static int atapi_id_update(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
611709Smlf ata_pkt_t *ata_pktp);
621709Smlf
631709Smlf
641709Smlf /* external dependencies */
651709Smlf
661709Smlf char _depends_on[] = "misc/scsi";
671709Smlf
681709Smlf /*
691709Smlf * Local static data
701709Smlf */
711709Smlf
721709Smlf #if 0
731709Smlf static ddi_dma_lim_t atapi_dma_limits = {
741709Smlf 0, /* address low */
751709Smlf 0xffffffffU, /* address high */
761709Smlf 0, /* counter max */
771709Smlf 1, /* burstsize */
781709Smlf DMA_UNIT_8, /* minimum xfer */
791709Smlf 0, /* dma speed */
801709Smlf (uint_t)DMALIM_VER0, /* version */
811709Smlf 0xffffffffU, /* address register */
821709Smlf 0xffffffffU, /* counter register */
831709Smlf 1, /* granular */
841709Smlf 1, /* scatter/gather list length */
851709Smlf 0xffffffffU /* request size */
861709Smlf };
871709Smlf #endif
881709Smlf
891709Smlf static int atapi_use_static_geometry = TRUE;
901709Smlf static int atapi_arq_enable = TRUE;
911709Smlf
921709Smlf
931709Smlf /*
941709Smlf *
951709Smlf * Call SCSA init to initialize the ATAPI half of the driver
961709Smlf *
971709Smlf */
981709Smlf
991709Smlf int
atapi_attach(ata_ctl_t * ata_ctlp)1001709Smlf atapi_attach(ata_ctl_t *ata_ctlp)
1011709Smlf {
1021709Smlf dev_info_t *dip = ata_ctlp->ac_dip;
1031709Smlf scsi_hba_tran_t *tran;
1041709Smlf
1051709Smlf ADBG_TRACE(("atapi_init entered\n"));
1061709Smlf
1071709Smlf /* allocate transport structure */
1081709Smlf
1091709Smlf tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
1101709Smlf
1111709Smlf if (tran == NULL) {
1121709Smlf ADBG_WARN(("atapi_init: scsi_hba_tran_alloc failed\n"));
1131709Smlf goto errout;
1141709Smlf }
1151709Smlf
1161709Smlf ata_ctlp->ac_atapi_tran = tran;
1171709Smlf ata_ctlp->ac_flags |= AC_SCSI_HBA_TRAN_ALLOC;
1181709Smlf
1191709Smlf /* initialize transport structure */
1201709Smlf
1211709Smlf tran->tran_hba_private = ata_ctlp;
1221709Smlf tran->tran_tgt_private = NULL;
1231709Smlf
1241709Smlf tran->tran_tgt_init = atapi_tran_tgt_init;
1251709Smlf tran->tran_tgt_probe = atapi_tran_tgt_probe;
1261709Smlf tran->tran_tgt_free = atapi_tran_tgt_free;
1271709Smlf tran->tran_start = atapi_tran_start;
1281709Smlf tran->tran_reset = atapi_tran_reset;
1291709Smlf tran->tran_abort = atapi_tran_abort;
1301709Smlf tran->tran_getcap = atapi_tran_getcap;
1311709Smlf tran->tran_setcap = atapi_tran_setcap;
1321709Smlf tran->tran_init_pkt = atapi_tran_init_pkt;
1331709Smlf tran->tran_destroy_pkt = atapi_tran_destroy_pkt;
1341709Smlf tran->tran_dmafree = atapi_tran_dmafree;
1351709Smlf tran->tran_sync_pkt = atapi_tran_sync_pkt;
1361709Smlf
1371709Smlf if (scsi_hba_attach_setup(ata_ctlp->ac_dip, &ata_pciide_dma_attr, tran,
1385792Slh195018 SCSI_HBA_TRAN_CLONE) != DDI_SUCCESS) {
1391709Smlf ADBG_WARN(("atapi_init: scsi_hba_attach_setup failed\n"));
1401709Smlf goto errout;
1411709Smlf }
1421709Smlf
1431709Smlf ata_ctlp->ac_flags |= AC_SCSI_HBA_ATTACH;
1441709Smlf
1451709Smlf return (TRUE);
1461709Smlf
1471709Smlf errout:
1481709Smlf atapi_detach(ata_ctlp);
1491709Smlf return (FALSE);
1501709Smlf }
1511709Smlf
1521709Smlf
1531709Smlf /*
1541709Smlf *
1551709Smlf * destroy the atapi sub-system
1561709Smlf *
1571709Smlf */
1581709Smlf
1591709Smlf void
atapi_detach(ata_ctl_t * ata_ctlp)1601709Smlf atapi_detach(
1611709Smlf ata_ctl_t *ata_ctlp)
1621709Smlf {
1631709Smlf ADBG_TRACE(("atapi_detach entered\n"));
1641709Smlf
1651709Smlf if (ata_ctlp->ac_flags & AC_SCSI_HBA_ATTACH)
1663446Smrj (void) scsi_hba_detach(ata_ctlp->ac_dip);
1671709Smlf
1681709Smlf if (ata_ctlp->ac_flags & AC_SCSI_HBA_TRAN_ALLOC)
1691709Smlf scsi_hba_tran_free(ata_ctlp->ac_atapi_tran);
1701709Smlf }
1711709Smlf
1721709Smlf
1731709Smlf
1741709Smlf /*
1751709Smlf *
1761709Smlf * initialize the ATAPI drive's soft-state based on the
1771709Smlf * response to IDENTIFY PACKET DEVICE command
1781709Smlf *
1791709Smlf */
1801709Smlf
1811709Smlf int
atapi_init_drive(ata_drv_t * ata_drvp)1821709Smlf atapi_init_drive(
1831709Smlf ata_drv_t *ata_drvp)
1841709Smlf {
1856412Syt160523 ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
1866412Syt160523
1871709Smlf ADBG_TRACE(("atapi_init_drive entered\n"));
1881709Smlf
1891709Smlf /* Determine ATAPI CDB size */
1907554SAda.Feng@Sun.COM (void) atapi_id_update(ata_ctlp, ata_drvp, NULL);
1911709Smlf
1921709Smlf switch (ata_drvp->ad_id.ai_config & ATAPI_ID_CFG_PKT_SZ) {
1931709Smlf
1941709Smlf case ATAPI_ID_CFG_PKT_12B:
1951709Smlf ata_drvp->ad_cdb_len = 12;
1961709Smlf break;
1971709Smlf case ATAPI_ID_CFG_PKT_16B:
1981709Smlf ata_drvp->ad_cdb_len = 16;
1991709Smlf break;
2001709Smlf default:
2011709Smlf ADBG_WARN(("atapi_init_drive: bad pkt size support\n"));
2021709Smlf return (FALSE);
2031709Smlf }
2041709Smlf
2051709Smlf /* determine if drive gives an intr when it wants the CDB */
2061709Smlf
2071709Smlf if ((ata_drvp->ad_id.ai_config & ATAPI_ID_CFG_DRQ_TYPE) !=
2081709Smlf ATAPI_ID_CFG_DRQ_INTR)
2091709Smlf ata_drvp->ad_flags |= AD_NO_CDB_INTR;
2101709Smlf
2116412Syt160523 /*
2126412Syt160523 * Some devices may have no DMA mode enabled (UDMA or MWDMA)
2136412Syt160523 * by default, so here we need check and enable DMA if none
2146412Syt160523 * mode is selected.
2156412Syt160523 */
2166412Syt160523 if (ata_set_dma_mode(ata_ctlp, ata_drvp) == TRUE) {
2176412Syt160523 /* Update the IDENTIFY PACKET DEVICE data */
2186412Syt160523 (void) atapi_id_update(ata_ctlp, ata_drvp, NULL);
2196412Syt160523 }
2206412Syt160523
2211709Smlf return (TRUE);
2221709Smlf }
2231709Smlf
2241709Smlf
2251709Smlf /*
2261709Smlf *
2271709Smlf * destroy an atapi drive
2281709Smlf *
2291709Smlf */
2301709Smlf
2311709Smlf /* ARGSUSED */
2321709Smlf void
atapi_uninit_drive(ata_drv_t * ata_drvp)2331709Smlf atapi_uninit_drive(
2341709Smlf ata_drv_t *ata_drvp)
2351709Smlf {
2361709Smlf ADBG_TRACE(("atapi_uninit_drive entered\n"));
2371709Smlf }
2381709Smlf
2391709Smlf /*
2401709Smlf *
2411709Smlf * Issue an IDENTIFY PACKET (ATAPI) DEVICE command
2421709Smlf *
2431709Smlf */
2441709Smlf
2451709Smlf int
atapi_id(ddi_acc_handle_t io_hdl1,caddr_t ioaddr1,ddi_acc_handle_t io_hdl2,caddr_t ioaddr2,struct ata_id * ata_idp)2461709Smlf atapi_id(
2471709Smlf ddi_acc_handle_t io_hdl1,
2481709Smlf caddr_t ioaddr1,
2491709Smlf ddi_acc_handle_t io_hdl2,
2501709Smlf caddr_t ioaddr2,
2511709Smlf struct ata_id *ata_idp)
2521709Smlf {
2531709Smlf int rc;
2541709Smlf
2551709Smlf ADBG_TRACE(("atapi_id entered\n"));
2561709Smlf
2571709Smlf rc = ata_id_common(ATC_ID_PACKET_DEVICE, FALSE, io_hdl1, ioaddr1,
2585792Slh195018 io_hdl2, ioaddr2, ata_idp);
2591709Smlf
2601709Smlf if (!rc)
2611709Smlf return (FALSE);
2621709Smlf
2631709Smlf if ((ata_idp->ai_config & ATAC_ATAPI_TYPE_MASK) != ATAC_ATAPI_TYPE)
2641709Smlf return (FALSE);
2651709Smlf
2661709Smlf return (TRUE);
2671709Smlf }
2681709Smlf
2691709Smlf
2701709Smlf /*
2711709Smlf *
2721709Smlf * Check the device's register block for the ATAPI signature.
2731709Smlf *
2741709Smlf * Although the spec says the sector count, sector number and device/head
2751709Smlf * registers are also part of the signature, for some unknown reason, this
2761709Smlf * routine only checks the cyl hi and cyl low registers. I'm just
2771709Smlf * guessing, but it might be because ATA and ATAPI devices return
2781709Smlf * identical values in those registers and we actually rely on the
2791709Smlf * IDENTIFY DEVICE and IDENTIFY PACKET DEVICE commands to recognize the
2801709Smlf * device type.
2811709Smlf *
2821709Smlf */
2831709Smlf
2841709Smlf int
atapi_signature(ddi_acc_handle_t io_hdl,caddr_t ioaddr)2851709Smlf atapi_signature(
2861709Smlf ddi_acc_handle_t io_hdl,
2871709Smlf caddr_t ioaddr)
2881709Smlf {
2891709Smlf int rc = FALSE;
2901709Smlf ADBG_TRACE(("atapi_signature entered\n"));
2911709Smlf
2921709Smlf if (ddi_get8(io_hdl, (uchar_t *)ioaddr + AT_HCYL) == ATAPI_SIG_HI &&
2935792Slh195018 ddi_get8(io_hdl, (uchar_t *)ioaddr + AT_LCYL) != ATAPI_SIG_LO)
2941709Smlf rc = TRUE;
2951709Smlf
2961709Smlf /*
2971709Smlf * The following is a little bit of bullet proofing.
2981709Smlf *
2991709Smlf * When some drives are configured on a master-only bus they
3001709Smlf * "shadow" their registers for the not-present slave drive.
3011709Smlf * This is bogus and if you're not careful it may cause a
3021709Smlf * master-only drive to be mistakenly recognized as both
3031709Smlf * master and slave. By clearing the signature registers here
3041709Smlf * I can make certain that when ata_drive_type() switches from
3051709Smlf * the master to slave drive that I'll read back non-signature
3061709Smlf * values regardless of whether the master-only drive does
3071709Smlf * the "shadow" register trick. This prevents a bogus
3081709Smlf * IDENTIFY PACKET DEVICE command from being issued which
3091709Smlf * a really bogus master-only drive will return "shadow"
3101709Smlf * data for.
3111709Smlf */
3121709Smlf ddi_put8(io_hdl, (uchar_t *)ioaddr + AT_HCYL, 0);
3131709Smlf ddi_put8(io_hdl, (uchar_t *)ioaddr + AT_LCYL, 0);
3141709Smlf
3151709Smlf return (rc);
3161709Smlf }
3171709Smlf
3181709Smlf
3191709Smlf /*
3201709Smlf *
3211709Smlf * SCSA tran_tgt_init entry point
3221709Smlf *
3231709Smlf */
3241709Smlf
3251709Smlf /* ARGSUSED */
3261709Smlf static int
atapi_tran_tgt_init(dev_info_t * hba_dip,dev_info_t * tgt_dip,scsi_hba_tran_t * hba_tran,struct scsi_device * sd)3271709Smlf atapi_tran_tgt_init(
3281709Smlf dev_info_t *hba_dip,
3291709Smlf dev_info_t *tgt_dip,
3301709Smlf scsi_hba_tran_t *hba_tran,
3311709Smlf struct scsi_device *sd)
3321709Smlf {
3331709Smlf gtgt_t *gtgtp; /* GHD's per-target-instance structure */
3341709Smlf ata_ctl_t *ata_ctlp;
3351709Smlf ata_tgt_t *ata_tgtp;
3361709Smlf ata_drv_t *ata_drvp;
3371709Smlf struct scsi_address *ap;
3381709Smlf int rc = DDI_SUCCESS;
3391709Smlf
3401709Smlf ADBG_TRACE(("atapi_tran_tgt_init entered\n"));
3411709Smlf
3421709Smlf /*
3431709Smlf * Qualification of targ, lun, and ATAPI device presence
3441709Smlf * have already been taken care of by ata_bus_ctl
3451709Smlf */
3461709Smlf
3471709Smlf /* store pointer to drive struct in cloned tran struct */
3481709Smlf
3491709Smlf ata_ctlp = TRAN2CTL(hba_tran);
3501709Smlf ap = &sd->sd_address;
3511709Smlf
3521709Smlf ata_drvp = CTL2DRV(ata_ctlp, ap->a_target, ap->a_lun);
3531709Smlf
3541709Smlf /*
3551709Smlf * Create the "atapi" property so the target driver knows
3561709Smlf * to use the correct set of SCSI commands
3571709Smlf */
3581709Smlf if (!ata_prop_create(tgt_dip, ata_drvp, "atapi")) {
3591709Smlf return (DDI_FAILURE);
3601709Smlf }
3611709Smlf
3621709Smlf gtgtp = ghd_target_init(hba_dip, tgt_dip, &ata_ctlp->ac_ccc,
3631709Smlf sizeof (ata_tgt_t), ata_ctlp,
3641709Smlf ap->a_target, ap->a_lun);
3651709Smlf
3661709Smlf /* tran_tgt_private points to gtgt_t */
3671709Smlf hba_tran->tran_tgt_private = gtgtp;
3681709Smlf
3691709Smlf /* gt_tgt_private points to ata_tgt_t */
3701709Smlf ata_tgtp = GTGTP2ATATGTP(gtgtp);
3711709Smlf
3721709Smlf /* initialize the per-target-instance data */
3731709Smlf ata_tgtp->at_drvp = ata_drvp;
3741709Smlf ata_tgtp->at_dma_attr = ata_pciide_dma_attr;
3751709Smlf ata_tgtp->at_dma_attr.dma_attr_maxxfer =
3761709Smlf ata_ctlp->ac_max_transfer << SCTRSHFT;
3771709Smlf
3781709Smlf return (rc);
3791709Smlf }
3801709Smlf
3811709Smlf
3821709Smlf /*
3831709Smlf *
3841709Smlf * SCSA tran_tgt_probe entry point
3851709Smlf *
3861709Smlf */
3871709Smlf
3881709Smlf static int
atapi_tran_tgt_probe(struct scsi_device * sd,int (* callback)(void))3891709Smlf atapi_tran_tgt_probe(struct scsi_device *sd, int (*callback)(void))
3901709Smlf {
3911709Smlf ADBG_TRACE(("atapi_tran_tgt_probe entered\n"));
3921709Smlf
3931709Smlf return (scsi_hba_probe(sd, callback));
3941709Smlf }
3951709Smlf
3961709Smlf
3971709Smlf /*
3981709Smlf *
3991709Smlf * SCSA tran_tgt_free entry point
4001709Smlf *
4011709Smlf */
4021709Smlf
4031709Smlf /* ARGSUSED */
4041709Smlf static void
atapi_tran_tgt_free(dev_info_t * hba_dip,dev_info_t * tgt_dip,scsi_hba_tran_t * hba_tran,struct scsi_device * sd)4051709Smlf atapi_tran_tgt_free(
4061709Smlf dev_info_t *hba_dip,
4071709Smlf dev_info_t *tgt_dip,
4081709Smlf scsi_hba_tran_t *hba_tran,
4091709Smlf struct scsi_device *sd)
4101709Smlf {
4111709Smlf ADBG_TRACE(("atapi_tran_tgt_free entered\n"));
4121709Smlf
4131709Smlf ghd_target_free(hba_dip, tgt_dip, &TRAN2ATAP(hba_tran)->ac_ccc,
4145792Slh195018 TRAN2GTGTP(hba_tran));
4151709Smlf hba_tran->tran_tgt_private = NULL;
4161709Smlf }
4171709Smlf
4181709Smlf
4191709Smlf
4201709Smlf /*
4211709Smlf *
4221709Smlf * SCSA tran_abort entry point
4231709Smlf *
4241709Smlf */
4251709Smlf
4261709Smlf /* ARGSUSED */
4271709Smlf static int
atapi_tran_abort(struct scsi_address * ap,struct scsi_pkt * spktp)4281709Smlf atapi_tran_abort(
4291709Smlf struct scsi_address *ap,
4301709Smlf struct scsi_pkt *spktp)
4311709Smlf {
4321709Smlf ADBG_TRACE(("atapi_tran_abort entered\n"));
4331709Smlf
4341709Smlf if (spktp) {
4351709Smlf return (ghd_tran_abort(&ADDR2CTL(ap)->ac_ccc, PKTP2GCMDP(spktp),
4365792Slh195018 ADDR2GTGTP(ap), NULL));
4371709Smlf }
4381709Smlf
4391709Smlf return (ghd_tran_abort_lun(&ADDR2CTL(ap)->ac_ccc, ADDR2GTGTP(ap),
4405792Slh195018 NULL));
4411709Smlf }
4421709Smlf
4431709Smlf
4441709Smlf /*
4451709Smlf *
4461709Smlf * SCSA tran_reset entry point
4471709Smlf *
4481709Smlf */
4491709Smlf
4501709Smlf /* ARGSUSED */
4511709Smlf static int
atapi_tran_reset(struct scsi_address * ap,int level)4521709Smlf atapi_tran_reset(
4531709Smlf struct scsi_address *ap,
4541709Smlf int level)
4551709Smlf {
4561709Smlf ADBG_TRACE(("atapi_tran_reset entered\n"));
4571709Smlf
4581709Smlf if (level == RESET_TARGET)
4591709Smlf return (ghd_tran_reset_target(&ADDR2CTL(ap)->ac_ccc,
4601709Smlf ADDR2GTGTP(ap), NULL));
4611709Smlf if (level == RESET_ALL)
4621709Smlf return (ghd_tran_reset_bus(&ADDR2CTL(ap)->ac_ccc,
4631709Smlf ADDR2GTGTP(ap), NULL));
4641709Smlf return (FALSE);
4651709Smlf
4661709Smlf }
4671709Smlf
4681709Smlf
4691709Smlf /*
4701709Smlf *
4711709Smlf * SCSA tran_setcap entry point
4721709Smlf *
4731709Smlf */
4741709Smlf
4751709Smlf static int
atapi_tran_setcap(struct scsi_address * ap,char * capstr,int value,int whom)4761709Smlf atapi_tran_setcap(
4771709Smlf struct scsi_address *ap,
4781709Smlf char *capstr,
4791709Smlf int value,
4801709Smlf int whom)
4811709Smlf {
4821709Smlf gtgt_t *gtgtp = ADDR2GTGTP(ap);
4831709Smlf ata_tgt_t *tgtp = GTGTP2ATATGTP(gtgtp);
4841709Smlf
4851709Smlf ADBG_TRACE(("atapi_tran_setcap entered\n"));
4861709Smlf
4871709Smlf switch (scsi_hba_lookup_capstr(capstr)) {
4881709Smlf case SCSI_CAP_SECTOR_SIZE:
4891709Smlf tgtp->at_dma_attr.dma_attr_granular = (uint_t)value;
4901709Smlf return (TRUE);
4911709Smlf
4921709Smlf case SCSI_CAP_ARQ:
4931709Smlf if (whom) {
4941709Smlf tgtp->at_arq = value;
4951709Smlf return (TRUE);
4961709Smlf }
4971709Smlf break;
4981709Smlf
4991709Smlf case SCSI_CAP_TOTAL_SECTORS:
5001709Smlf tgtp->at_total_sectors = value;
5011709Smlf return (TRUE);
5021709Smlf }
5031709Smlf return (FALSE);
5041709Smlf }
5051709Smlf
5061709Smlf
5071709Smlf /*
5081709Smlf *
5091709Smlf * SCSA tran_getcap entry point
5101709Smlf *
5111709Smlf */
5121709Smlf
5131709Smlf static int
atapi_tran_getcap(struct scsi_address * ap,char * capstr,int whom)5141709Smlf atapi_tran_getcap(
5151709Smlf struct scsi_address *ap,
5161709Smlf char *capstr,
5171709Smlf int whom)
5181709Smlf {
5191709Smlf struct ata_id ata_id;
5201709Smlf struct ata_id *ata_idp;
5211709Smlf ata_ctl_t *ata_ctlp;
5221709Smlf ata_drv_t *ata_drvp;
5231709Smlf gtgt_t *gtgtp;
5241709Smlf int rval = -1;
5251709Smlf
5261709Smlf ADBG_TRACE(("atapi_tran_getcap entered\n"));
5271709Smlf
5281709Smlf if (capstr == NULL || whom == 0)
5291709Smlf return (-1);
5301709Smlf
5311709Smlf ata_ctlp = ADDR2CTL(ap);
5321709Smlf
5331709Smlf switch (scsi_hba_lookup_capstr(capstr)) {
5341709Smlf case SCSI_CAP_ARQ:
5351709Smlf rval = TRUE;
5361709Smlf break;
5371709Smlf
5381709Smlf case SCSI_CAP_INITIATOR_ID:
5391709Smlf rval = 7;
5401709Smlf break;
5411709Smlf
5421709Smlf case SCSI_CAP_DMA_MAX:
5431709Smlf /* XXX - what should the real limit be?? */
5441709Smlf /* limit to 64K ??? */
5451709Smlf rval = 4096 * (ATA_DMA_NSEGS - 1);
5461709Smlf break;
5471709Smlf
5481709Smlf case SCSI_CAP_GEOMETRY:
5491709Smlf /* Default geometry */
5501709Smlf if (atapi_use_static_geometry) {
5511709Smlf rval = ATAPI_HEADS << 16 | ATAPI_SECTORS_PER_TRK;
5521709Smlf break;
5531709Smlf }
5541709Smlf
5551709Smlf /* this code is currently not used */
5561709Smlf
5571709Smlf ata_drvp = CTL2DRV(ata_ctlp, ap->a_target, ap->a_lun);
5581709Smlf gtgtp = ADDR2GTGTP(ap);
5591709Smlf
5601709Smlf /*
5611709Smlf * retrieve the current IDENTIFY PACKET DEVICE info
5621709Smlf */
5631709Smlf if (!ata_queue_cmd(atapi_id_update, &ata_id, ata_ctlp,
5645792Slh195018 ata_drvp, gtgtp)) {
5651709Smlf ADBG_TRACE(("atapi_tran_getcap geometry failed"));
5661709Smlf return (0);
5671709Smlf }
5681709Smlf
5691709Smlf /*
5701709Smlf * save the new response data
5711709Smlf */
5721709Smlf ata_idp = &ata_drvp->ad_id;
5731709Smlf *ata_idp = ata_id;
5741709Smlf
5751709Smlf switch ((ata_idp->ai_config >> 8) & 0xf) {
5761709Smlf case DTYPE_RODIRECT:
5771709Smlf rval = ATAPI_HEADS << 16 | ATAPI_SECTORS_PER_TRK;
5781709Smlf break;
5791709Smlf case DTYPE_DIRECT:
5801709Smlf case DTYPE_OPTICAL:
5811709Smlf rval = (ata_idp->ai_curheads << 16) |
5825792Slh195018 ata_idp->ai_cursectrk;
5831709Smlf break;
5841709Smlf default:
5851709Smlf rval = 0;
5861709Smlf }
5871709Smlf break;
5881709Smlf }
5891709Smlf
5901709Smlf return (rval);
5911709Smlf }
5921709Smlf
5931709Smlf
5941709Smlf
5951709Smlf /*
5961709Smlf *
5971709Smlf * SCSA tran_init_pkt entry point
5981709Smlf *
5991709Smlf */
6001709Smlf
6011709Smlf static struct scsi_pkt *
atapi_tran_init_pkt(struct scsi_address * ap,struct scsi_pkt * spktp,struct buf * bp,int cmdlen,int statuslen,int tgtlen,int flags,int (* callback)(caddr_t),caddr_t arg)6021709Smlf atapi_tran_init_pkt(
6031709Smlf struct scsi_address *ap,
6041709Smlf struct scsi_pkt *spktp,
6051709Smlf struct buf *bp,
6061709Smlf int cmdlen,
6071709Smlf int statuslen,
6081709Smlf int tgtlen,
6091709Smlf int flags,
6101709Smlf int (*callback)(caddr_t),
6111709Smlf caddr_t arg)
6121709Smlf {
6131709Smlf gtgt_t *gtgtp = ADDR2GTGTP(ap);
6141709Smlf ata_tgt_t *ata_tgtp = GTGTP2ATATGTP(gtgtp);
6151709Smlf ata_ctl_t *ata_ctlp = ADDR2CTL(ap);
6161709Smlf ata_pkt_t *ata_pktp;
6171709Smlf struct scsi_pkt *new_spktp;
6181709Smlf ddi_dma_attr_t *sg_attrp;
6191709Smlf int bytes;
6201709Smlf
6211709Smlf ADBG_TRACE(("atapi_tran_init_pkt entered\n"));
6221709Smlf
6231709Smlf
6241709Smlf /*
6251709Smlf * Determine whether to do PCI-IDE DMA setup, start out by
6261709Smlf * assuming we're not.
6271709Smlf */
6281709Smlf sg_attrp = NULL;
6291709Smlf
6301709Smlf if (bp == NULL) {
6311709Smlf /* no data to transfer */
6321709Smlf goto skip_dma_setup;
6331709Smlf }
6341709Smlf
6351709Smlf if (bp->b_bcount == 0) {
6361709Smlf /* no data to transfer */
6371709Smlf goto skip_dma_setup;
6381709Smlf }
6391709Smlf
6401709Smlf if ((GTGTP2ATADRVP(ADDR2GTGTP(ap))->ad_pciide_dma == ATA_DMA_OFF)) {
6411709Smlf goto skip_dma_setup;
6421709Smlf }
6431709Smlf
6441709Smlf if (ata_dma_disabled)
6451709Smlf goto skip_dma_setup;
6461709Smlf
6471709Smlf
6481709Smlf /*
6491709Smlf * The PCI-IDE DMA engine is brain-damaged and can't
6501709Smlf * DMA non-aligned buffers.
6511709Smlf */
6521709Smlf if (((bp->b_flags & B_PAGEIO) == 0) &&
6531709Smlf ((uintptr_t)bp->b_un.b_addr) & PCIIDE_PRDE_ADDR_MASK) {
6541709Smlf /*
6551709Smlf * if the virtual address isn't aligned, then the
6561709Smlf * physical address also isn't aligned.
6571709Smlf */
6581709Smlf goto skip_dma_setup;
6591709Smlf }
6601709Smlf
6611709Smlf /*
6621709Smlf * It also insists that the byte count must be even.
6631709Smlf */
6641709Smlf if (bp->b_bcount & 1) {
6651709Smlf /* something odd here */
6661709Smlf goto skip_dma_setup;
6671709Smlf }
6681709Smlf
6691709Smlf /*
6701709Smlf * Huzza! We're really going to do it
6711709Smlf */
6721709Smlf sg_attrp = &ata_tgtp->at_dma_attr;
6731709Smlf
6741709Smlf
6751709Smlf skip_dma_setup:
6761709Smlf
6771709Smlf /*
6781709Smlf * Call GHD packet init function
6791709Smlf */
6801709Smlf
6811709Smlf new_spktp = ghd_tran_init_pkt_attr(&ata_ctlp->ac_ccc, ap, spktp, bp,
6825792Slh195018 cmdlen, statuslen, tgtlen, flags,
6835792Slh195018 callback, arg, sizeof (ata_pkt_t), sg_attrp);
6841709Smlf
6851709Smlf if (new_spktp == NULL)
6861709Smlf return (NULL);
6871709Smlf
6881709Smlf ata_pktp = SPKT2APKT(new_spktp);
6891709Smlf ata_pktp->ap_cdbp = new_spktp->pkt_cdbp;
6905792Slh195018 if (statuslen > 255) {
6915792Slh195018 statuslen = sizeof (struct scsi_arq_status);
6925792Slh195018 }
6931709Smlf ata_pktp->ap_statuslen = (uchar_t)statuslen;
6941709Smlf
6951709Smlf /* reset data direction flags */
6961709Smlf if (spktp)
6971709Smlf ata_pktp->ap_flags &= ~(AP_READ | AP_WRITE);
6981709Smlf
6991709Smlf /*
7001709Smlf * check for ARQ mode
7011709Smlf */
7021709Smlf if (atapi_arq_enable == TRUE &&
7035792Slh195018 ata_tgtp->at_arq == TRUE &&
7045792Slh195018 ata_pktp->ap_statuslen >= sizeof (struct scsi_arq_status)) {
7051709Smlf ADBG_TRACE(("atapi_tran_init_pkt ARQ\n"));
7061709Smlf ata_pktp->ap_scbp =
7071709Smlf (struct scsi_arq_status *)new_spktp->pkt_scbp;
7081709Smlf ata_pktp->ap_flags |= AP_ARQ_ON_ERROR;
7091709Smlf }
7101709Smlf
7111709Smlf /*
7121709Smlf * fill these with zeros for ATA/ATAPI-4 compatibility
7131709Smlf */
7141709Smlf ata_pktp->ap_sec = 0;
7151709Smlf ata_pktp->ap_count = 0;
7161709Smlf
7171709Smlf if (ata_pktp->ap_sg_cnt) {
7181709Smlf ASSERT(bp != NULL);
7191709Smlf /* determine direction to program the DMA engine later */
7201709Smlf if (bp->b_flags & B_READ) {
7211709Smlf ata_pktp->ap_flags |= AP_READ;
7221709Smlf } else {
7231709Smlf ata_pktp->ap_flags |= AP_WRITE;
7241709Smlf }
7251709Smlf ata_pktp->ap_pciide_dma = TRUE;
7261709Smlf ata_pktp->ap_hicyl = 0;
7271709Smlf ata_pktp->ap_lwcyl = 0;
7281709Smlf return (new_spktp);
7291709Smlf }
7301709Smlf
7311709Smlf /*
7321709Smlf * Since we're not using DMA, we need to map the buffer into
7331709Smlf * kernel address space
7341709Smlf */
7351709Smlf
7361709Smlf ata_pktp->ap_pciide_dma = FALSE;
7371709Smlf if (bp && bp->b_bcount) {
7381709Smlf /*
7391709Smlf * If this is a fresh request map the buffer and
7401709Smlf * reset the ap_baddr pointer and the current offset
7411709Smlf * and byte count.
7421709Smlf *
7431709Smlf * The ap_boffset is used to set the ap_v_addr ptr at
7441709Smlf * the start of each I/O request.
7451709Smlf *
7461709Smlf * The ap_bcount is used to update ap_boffset when the
7471709Smlf * target driver requests the next segment.
7481709Smlf *
7491709Smlf */
7501709Smlf if (cmdlen) {
7511709Smlf bp_mapin(bp);
7521709Smlf ata_pktp->ap_baddr = bp->b_un.b_addr;
7531709Smlf ata_pktp->ap_bcount = 0;
7541709Smlf ata_pktp->ap_boffset = 0;
7551709Smlf }
7561709Smlf ASSERT(ata_pktp->ap_baddr != NULL);
7571709Smlf
7581709Smlf /* determine direction for the PIO FSM */
7591709Smlf if (bp->b_flags & B_READ) {
7601709Smlf ata_pktp->ap_flags |= AP_READ;
7611709Smlf } else {
7621709Smlf ata_pktp->ap_flags |= AP_WRITE;
7631709Smlf }
7641709Smlf
7651709Smlf /*
7661709Smlf * If the drive has the Single Sector bug, limit
7671709Smlf * the transfer to a single sector. This assumes
7681709Smlf * ATAPI CD drives always use 2k sectors.
7691709Smlf */
7701709Smlf if (GTGTP2ATADRVP(ADDR2GTGTP(ap))->ad_flags & AD_1SECTOR) {
7711709Smlf size_t resid;
7721709Smlf size_t tmp;
7731709Smlf
7741709Smlf /* adjust offset based on prior request */
7751709Smlf ata_pktp->ap_boffset += ata_pktp->ap_bcount;
7761709Smlf
7771709Smlf /* compute number of bytes left to transfer */
7781709Smlf resid = bp->b_bcount - ata_pktp->ap_boffset;
7791709Smlf
7801709Smlf /* limit the transfer to 2k */
7811709Smlf tmp = MIN(2048, resid);
7821709Smlf ata_pktp->ap_bcount = tmp;
7831709Smlf
7841709Smlf /* tell target driver how much is left for next time */
7851709Smlf new_spktp->pkt_resid = resid - tmp;
7861709Smlf } else {
7871709Smlf /* do the whole request in one swell foop */
7881709Smlf ata_pktp->ap_bcount = bp->b_bcount;
7891709Smlf new_spktp->pkt_resid = 0;
7901709Smlf }
7911709Smlf
7921709Smlf } else {
7931709Smlf ata_pktp->ap_baddr = NULL;
7941709Smlf ata_pktp->ap_bcount = 0;
7951709Smlf ata_pktp->ap_boffset = 0;
7961709Smlf }
7971709Smlf
7981709Smlf /*
7991709Smlf * determine the size of each partial data transfer
8001709Smlf * to/from the drive
8011709Smlf */
8021709Smlf bytes = min(ata_pktp->ap_bcount, ATAPI_MAX_BYTES_PER_DRQ);
8031709Smlf ata_pktp->ap_hicyl = (uchar_t)(bytes >> 8);
8041709Smlf ata_pktp->ap_lwcyl = (uchar_t)bytes;
8051709Smlf return (new_spktp);
8061709Smlf }
8071709Smlf
8081709Smlf
8091709Smlf /*
8101709Smlf * GHD ccballoc callback
8111709Smlf *
8121709Smlf * Initializing the ata_pkt, and return the ptr to the gcmd_t to GHD.
8131709Smlf *
8141709Smlf */
8151709Smlf
8161709Smlf /* ARGSUSED */
8171709Smlf int
atapi_ccballoc(gtgt_t * gtgtp,gcmd_t * gcmdp,int cmdlen,int statuslen,int tgtlen,int ccblen)8181709Smlf atapi_ccballoc(
8191709Smlf gtgt_t *gtgtp,
8201709Smlf gcmd_t *gcmdp,
8211709Smlf int cmdlen,
8221709Smlf int statuslen,
8231709Smlf int tgtlen,
8241709Smlf int ccblen)
8251709Smlf
8261709Smlf {
8271709Smlf ata_drv_t *ata_drvp = GTGTP2ATADRVP(gtgtp);
8281709Smlf ata_pkt_t *ata_pktp = GCMD2APKT(gcmdp);
8291709Smlf
8301709Smlf ADBG_TRACE(("atapi_ccballoc entered\n"));
8311709Smlf
8321709Smlf /* set the back ptr from the ata_pkt to the gcmd_t */
8331709Smlf ata_pktp->ap_gcmdp = gcmdp;
8341709Smlf
8351709Smlf /* check length of SCSI CDB is not larger than drive expects */
8361709Smlf
8371709Smlf if (cmdlen > ata_drvp->ad_cdb_len) {
8381709Smlf ADBG_WARN(("atapi_ccballoc: SCSI CDB too large!\n"));
8391709Smlf return (FALSE);
8401709Smlf }
8411709Smlf
8421709Smlf /*
8431709Smlf * save length of the SCSI CDB, and calculate CDB padding
8441709Smlf * note that for convenience, padding is expressed in shorts.
8451709Smlf */
8461709Smlf
8471709Smlf ata_pktp->ap_cdb_len = (uchar_t)cmdlen;
8481709Smlf ata_pktp->ap_cdb_pad =
8491709Smlf ((unsigned)(ata_drvp->ad_cdb_len - cmdlen)) >> 1;
8501709Smlf
8511709Smlf /* set up callback functions */
8521709Smlf
8531709Smlf ata_pktp->ap_start = atapi_fsm_start;
8541709Smlf ata_pktp->ap_intr = atapi_fsm_intr;
8551709Smlf ata_pktp->ap_complete = atapi_complete;
8561709Smlf
8571709Smlf /* set-up for start */
8581709Smlf
8591709Smlf ata_pktp->ap_flags = AP_ATAPI;
8601709Smlf ata_pktp->ap_hd = ata_drvp->ad_drive_bits;
8611709Smlf ata_pktp->ap_cmd = ATC_PACKET;
8621709Smlf
8631709Smlf return (TRUE);
8641709Smlf }
8651709Smlf
8661709Smlf
8671709Smlf
8681709Smlf /*
8691709Smlf *
8701709Smlf * SCSA tran_destroy_pkt entry point
8711709Smlf *
8721709Smlf */
8731709Smlf
8741709Smlf static void
atapi_tran_destroy_pkt(struct scsi_address * ap,struct scsi_pkt * spktp)8751709Smlf atapi_tran_destroy_pkt(
8761709Smlf struct scsi_address *ap,
8771709Smlf struct scsi_pkt *spktp)
8781709Smlf {
8791709Smlf gcmd_t *gcmdp = PKTP2GCMDP(spktp);
8801709Smlf
8811709Smlf ADBG_TRACE(("atapi_tran_destroy_pkt entered\n"));
8821709Smlf
8831709Smlf if (gcmdp->cmd_dma_handle != NULL) {
8841709Smlf ghd_dmafree_attr(gcmdp);
8851709Smlf }
8861709Smlf
8871709Smlf ghd_pktfree(&ADDR2CTL(ap)->ac_ccc, ap, spktp);
8881709Smlf }
8891709Smlf
8901709Smlf
8911709Smlf
8921709Smlf /*
8931709Smlf *
8941709Smlf * GHD ccbfree callback function
8951709Smlf *
8961709Smlf */
8971709Smlf
8981709Smlf /* ARGSUSED */
8991709Smlf void
atapi_ccbfree(gcmd_t * gcmdp)9001709Smlf atapi_ccbfree(
9011709Smlf gcmd_t *gcmdp)
9021709Smlf {
9031709Smlf ADBG_TRACE(("atapi_ccbfree entered\n"));
9041709Smlf
9051709Smlf /* nothing to do */
9061709Smlf }
9071709Smlf
9081709Smlf
9091709Smlf /*
9101709Smlf *
9111709Smlf * SCSA tran_dmafree entry point
9121709Smlf *
9131709Smlf */
9141709Smlf
9151709Smlf /*ARGSUSED*/
9161709Smlf static void
atapi_tran_dmafree(struct scsi_address * ap,struct scsi_pkt * spktp)9171709Smlf atapi_tran_dmafree(
9181709Smlf struct scsi_address *ap,
9191709Smlf struct scsi_pkt *spktp)
9201709Smlf {
9211709Smlf gcmd_t *gcmdp = PKTP2GCMDP(spktp);
9221709Smlf
9231709Smlf ADBG_TRACE(("atapi_tran_dmafree entered\n"));
9241709Smlf
9251709Smlf if (gcmdp->cmd_dma_handle != NULL) {
9261709Smlf ghd_dmafree_attr(gcmdp);
9271709Smlf }
9281709Smlf }
9291709Smlf
9301709Smlf
9311709Smlf
9321709Smlf /*
9331709Smlf *
9341709Smlf * SCSA tran_sync_pkt entry point
9351709Smlf *
9361709Smlf */
9371709Smlf
9381709Smlf /*ARGSUSED*/
9391709Smlf static void
atapi_tran_sync_pkt(struct scsi_address * ap,struct scsi_pkt * spktp)9401709Smlf atapi_tran_sync_pkt(
9411709Smlf struct scsi_address *ap,
9421709Smlf struct scsi_pkt *spktp)
9431709Smlf {
9441709Smlf
9451709Smlf ADBG_TRACE(("atapi_tran_sync_pkt entered\n"));
9461709Smlf
9471709Smlf if (PKTP2GCMDP(spktp)->cmd_dma_handle != NULL) {
9481709Smlf ghd_tran_sync_pkt(ap, spktp);
9491709Smlf }
9501709Smlf }
9511709Smlf
9521709Smlf
9531709Smlf
9541709Smlf /*
9551709Smlf *
9561709Smlf * SCSA tran_start entry point
9571709Smlf *
9581709Smlf */
9591709Smlf
9601709Smlf /* ARGSUSED */
9611709Smlf static int
atapi_tran_start(struct scsi_address * ap,struct scsi_pkt * spktp)9621709Smlf atapi_tran_start(
9631709Smlf struct scsi_address *ap,
9641709Smlf struct scsi_pkt *spktp)
9651709Smlf {
9661709Smlf ata_pkt_t *ata_pktp = SPKT2APKT(spktp);
9671709Smlf ata_drv_t *ata_drvp = APKT2DRV(ata_pktp);
9681709Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
9691709Smlf gcmd_t *gcmdp = APKT2GCMD(ata_pktp);
9701709Smlf int polled = FALSE;
9711709Smlf int rc;
9721709Smlf
9731709Smlf ADBG_TRACE(("atapi_tran_start entered\n"));
9741709Smlf
9751709Smlf /*
9761709Smlf * Basic initialization performed each and every time a
9771709Smlf * scsi_pkt is submitted. A single scsi_pkt may be submitted
9781709Smlf * multiple times so this routine has to be idempotent. One
9791709Smlf * time initializations don't belong here.
9801709Smlf */
9811709Smlf
9821709Smlf /*
9831709Smlf * The ap_v_addr pointer is incremented by the PIO data
9841709Smlf * transfer routine as each word is transferred. Therefore, need
9851709Smlf * to reset ap_v_addr here (rather than atapi_tran_init_pkt())
9861709Smlf * in case the target resubmits the same pkt multiple times
9871709Smlf * (which is permitted by SCSA).
9881709Smlf */
9891709Smlf ata_pktp->ap_v_addr = ata_pktp->ap_baddr + ata_pktp->ap_boffset;
9901709Smlf
9911709Smlf /* ap_resid is decremented as the data transfer progresses */
9921709Smlf ata_pktp->ap_resid = ata_pktp->ap_bcount;
9931709Smlf
9941709Smlf /* clear error flags */
9951709Smlf ata_pktp->ap_flags &= (AP_ATAPI | AP_READ | AP_WRITE | AP_ARQ_ON_ERROR);
9961709Smlf spktp->pkt_reason = 0;
9971709Smlf spktp->pkt_state = 0;
9981709Smlf spktp->pkt_statistics = 0;
9991709Smlf
10001709Smlf /*
10011709Smlf * check for polling pkt
10021709Smlf */
10031709Smlf if (spktp->pkt_flags & FLAG_NOINTR) {
10041709Smlf polled = TRUE;
10051709Smlf }
10061709Smlf
10071709Smlf #ifdef ___just_ignore_unsupported_flags___
10081709Smlf /* driver cannot accept tagged commands */
10091709Smlf
10101709Smlf if (spktp->pkt_flags & (FLAG_HTAG|FLAG_OTAG|FLAG_STAG)) {
10111709Smlf spktp->pkt_reason = CMD_TRAN_ERR;
10121709Smlf return (TRAN_BADPKT);
10131709Smlf }
10141709Smlf #endif
10151709Smlf
10161709Smlf /* call common transport routine */
10171709Smlf
10181709Smlf rc = ghd_transport(&ata_ctlp->ac_ccc, gcmdp, gcmdp->cmd_gtgtp,
10195792Slh195018 spktp->pkt_time, polled, NULL);
10201709Smlf
10211709Smlf /* see if pkt was not accepted */
10221709Smlf
10231709Smlf if (rc != TRAN_ACCEPT)
10241709Smlf return (rc);
10251709Smlf
10261709Smlf return (rc);
10271709Smlf }
10281709Smlf
10291709Smlf
10301709Smlf /*
10311709Smlf *
10321709Smlf * GHD packet complete callback
10331709Smlf *
10341709Smlf */
10351709Smlf /* ARGSUSED */
10361709Smlf static void
atapi_complete(ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp,int do_callback)10371709Smlf atapi_complete(
10381709Smlf ata_drv_t *ata_drvp,
10391709Smlf ata_pkt_t *ata_pktp,
10401709Smlf int do_callback)
10411709Smlf {
10421709Smlf struct scsi_pkt *spktp = APKT2SPKT(ata_pktp);
10431709Smlf struct scsi_status *scsi_stat = (struct scsi_status *)spktp->pkt_scbp;
10441709Smlf
10451709Smlf ADBG_TRACE(("atapi_complete entered\n"));
10461709Smlf ADBG_TRANSPORT(("atapi_complete: pkt = 0x%p\n", ata_pktp));
10471709Smlf
10481709Smlf /* update resid */
10491709Smlf
10501709Smlf spktp->pkt_resid = ata_pktp->ap_resid;
10511709Smlf
10521709Smlf if (ata_pktp->ap_flags & AP_SENT_CMD) {
10531709Smlf spktp->pkt_state |=
10545792Slh195018 STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD;
10551709Smlf }
10561709Smlf if (ata_pktp->ap_flags & AP_XFERRED_DATA) {
10571709Smlf spktp->pkt_state |= STATE_XFERRED_DATA;
10581709Smlf }
10591709Smlf
10601709Smlf if (ata_pktp->ap_flags & AP_GOT_STATUS) {
10611709Smlf spktp->pkt_state |= STATE_GOT_STATUS;
10621709Smlf }
10631709Smlf
10641709Smlf /* check for fatal errors */
10651709Smlf
10661709Smlf if (ata_pktp->ap_flags & AP_TRAN_ERROR) {
10671709Smlf spktp->pkt_reason = CMD_TRAN_ERR;
10681709Smlf } else if (ata_pktp->ap_flags & AP_BUS_RESET) {
10691709Smlf spktp->pkt_reason = CMD_RESET;
10701709Smlf spktp->pkt_statistics |= STAT_BUS_RESET;
10711709Smlf } else if (ata_pktp->ap_flags & AP_DEV_RESET) {
10721709Smlf spktp->pkt_reason = CMD_RESET;
10731709Smlf spktp->pkt_statistics |= STAT_DEV_RESET;
10741709Smlf } else if (ata_pktp->ap_flags & AP_ABORT) {
10751709Smlf spktp->pkt_reason = CMD_ABORTED;
10761709Smlf spktp->pkt_statistics |= STAT_ABORTED;
10771709Smlf } else if (ata_pktp->ap_flags & AP_TIMEOUT) {
10781709Smlf spktp->pkt_reason = CMD_TIMEOUT;
10791709Smlf spktp->pkt_statistics |= STAT_TIMEOUT;
10801709Smlf } else {
10811709Smlf spktp->pkt_reason = CMD_CMPLT;
10821709Smlf }
10831709Smlf
10841709Smlf /* non-fatal errors */
10851709Smlf
10861709Smlf if (ata_pktp->ap_flags & AP_ERROR)
10871709Smlf scsi_stat->sts_chk = 1;
10881709Smlf else
10891709Smlf scsi_stat->sts_chk = 0;
10901709Smlf
10911709Smlf if (ata_pktp->ap_flags & AP_ARQ_ERROR) {
10921709Smlf ADBG_ARQ(("atapi_complete ARQ error 0x%p\n", ata_pktp));
10931709Smlf spktp->pkt_reason = CMD_TRAN_ERR;
10941709Smlf
10951709Smlf } else if (ata_pktp->ap_flags & AP_ARQ_OKAY) {
10961709Smlf static struct scsi_status zero_scsi_status = { 0 };
10971709Smlf struct scsi_arq_status *arqp;
10981709Smlf
10991709Smlf ADBG_ARQ(("atapi_complete ARQ okay 0x%p\n", ata_pktp));
11001709Smlf spktp->pkt_state |= STATE_ARQ_DONE;
11011709Smlf arqp = ata_pktp->ap_scbp;
11021709Smlf arqp->sts_rqpkt_reason = CMD_CMPLT;
11031709Smlf arqp->sts_rqpkt_state = STATE_XFERRED_DATA;
11041709Smlf arqp->sts_rqpkt_status = zero_scsi_status;
11051709Smlf arqp->sts_rqpkt_resid = 0;
11061709Smlf arqp->sts_rqpkt_statistics = 0;
11071709Smlf
11081709Smlf }
11091709Smlf
11101709Smlf ADBG_TRANSPORT(("atapi_complete: reason = 0x%x stats = 0x%x "
11111709Smlf "sts_chk = %d\n", spktp->pkt_reason, spktp->pkt_statistics,
11121709Smlf scsi_stat->sts_chk));
11131709Smlf
11141709Smlf if (do_callback && (spktp->pkt_comp))
11151709Smlf (*spktp->pkt_comp)(spktp);
11161709Smlf }
11171709Smlf
11181709Smlf
11191709Smlf
11201709Smlf /*
11211709Smlf * Update the IDENTIFY PACKET DEVICE info
11221709Smlf */
11231709Smlf
11241709Smlf static int
atapi_id_update(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)11251709Smlf atapi_id_update(
11261709Smlf ata_ctl_t *ata_ctlp,
11271709Smlf ata_drv_t *ata_drvp,
11281709Smlf ata_pkt_t *ata_pktp)
11291709Smlf {
11301709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
11311709Smlf caddr_t ioaddr1 = ata_ctlp->ac_ioaddr1;
11321709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
11331709Smlf caddr_t ioaddr2 = ata_ctlp->ac_ioaddr2;
11346412Syt160523 struct ata_id *aidp;
11351709Smlf int rc;
11361709Smlf
11371709Smlf /*
11381709Smlf * select the appropriate drive and LUN
11391709Smlf */
11401709Smlf ddi_put8(io_hdl1, (uchar_t *)ioaddr1 + AT_DRVHD,
11415792Slh195018 ata_drvp->ad_drive_bits);
11424852Smlf ata_nsecwait(400);
11431709Smlf
11441709Smlf /*
11451709Smlf * make certain the drive is selected, and wait for not busy
11461709Smlf */
11471709Smlf if (!ata_wait(io_hdl2, ioaddr2, ATS_DRDY, ATS_BSY, 5 * 1000000)) {
11481709Smlf ADBG_ERROR(("atapi_id_update: select failed\n"));
11496412Syt160523 if (ata_pktp != NULL)
11506412Syt160523 ata_pktp->ap_flags |= AP_ERROR;
11511709Smlf return (ATA_FSM_RC_FINI);
11521709Smlf }
11531709Smlf
11546412Syt160523 if (ata_pktp != NULL)
11556412Syt160523 aidp = (struct ata_id *)ata_pktp->ap_v_addr;
11566412Syt160523 else
11576412Syt160523 aidp = &ata_drvp->ad_id;
11586412Syt160523
11591709Smlf rc = atapi_id(ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1,
11606412Syt160523 ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, aidp);
11617554SAda.Feng@Sun.COM if (rc) {
11627554SAda.Feng@Sun.COM swab(aidp->ai_drvser, aidp->ai_drvser,
11637554SAda.Feng@Sun.COM sizeof (aidp->ai_drvser));
11647554SAda.Feng@Sun.COM swab(aidp->ai_fw, aidp->ai_fw,
11657554SAda.Feng@Sun.COM sizeof (aidp->ai_fw));
11667554SAda.Feng@Sun.COM swab(aidp->ai_model, aidp->ai_model,
11677554SAda.Feng@Sun.COM sizeof (aidp->ai_model));
11687554SAda.Feng@Sun.COM }
11696412Syt160523
11706412Syt160523 if (ata_pktp == NULL)
11716412Syt160523 return (ATA_FSM_RC_FINI);
11721709Smlf
11731709Smlf if (!rc) {
11741709Smlf ata_pktp->ap_flags |= AP_ERROR;
11751709Smlf } else {
11761709Smlf ata_pktp->ap_flags |= AP_XFERRED_DATA;
11771709Smlf }
11781709Smlf return (ATA_FSM_RC_FINI);
11791709Smlf }
11801709Smlf
11811709Smlf
11821709Smlf
11831709Smlf /*
11841709Smlf * Both drives on the controller share a common pkt to do
11851709Smlf * ARQ processing. Therefore the pkt is only partially
11861709Smlf * initialized here. The rest of initialization occurs
11871709Smlf * just before starting the ARQ pkt when an error is
11881709Smlf * detected.
11891709Smlf */
11901709Smlf
11911709Smlf void
atapi_init_arq(ata_ctl_t * ata_ctlp)11921709Smlf atapi_init_arq(
11931709Smlf ata_ctl_t *ata_ctlp)
11941709Smlf {
11951709Smlf ata_pkt_t *arq_pktp = ata_ctlp->ac_arq_pktp;
11961709Smlf
11971709Smlf arq_pktp->ap_cdbp = ata_ctlp->ac_arq_cdb;
11981709Smlf arq_pktp->ap_cdb_len = sizeof (ata_ctlp->ac_arq_cdb);
11991709Smlf arq_pktp->ap_start = atapi_fsm_start;
12001709Smlf arq_pktp->ap_intr = atapi_fsm_intr;
12011709Smlf arq_pktp->ap_complete = atapi_complete;
12021709Smlf arq_pktp->ap_flags = AP_ATAPI;
12031709Smlf arq_pktp->ap_cmd = ATC_PACKET;
12041709Smlf
12051709Smlf ata_ctlp->ac_arq_cdb[0] = SCMD_REQUEST_SENSE;
12061709Smlf }
12077787SAda.Feng@Sun.COM
12087787SAda.Feng@Sun.COM void
atapi_reset_dma_mode(ata_drv_t * ata_drvp,int need_wait)1209*10452SAda.Feng@Sun.COM atapi_reset_dma_mode(ata_drv_t *ata_drvp, int need_wait)
12107787SAda.Feng@Sun.COM {
12117787SAda.Feng@Sun.COM ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
12127787SAda.Feng@Sun.COM
1213*10452SAda.Feng@Sun.COM /*
1214*10452SAda.Feng@Sun.COM * Some very old CD-ROM need to wait 500mS to
1215*10452SAda.Feng@Sun.COM * reset the DMA mode, so after reset the DMA
1216*10452SAda.Feng@Sun.COM * mode when resuming, check whether it was
1217*10452SAda.Feng@Sun.COM * enabled on the device, if not, delay 500mS
1218*10452SAda.Feng@Sun.COM * and reset it again. Then for normal DVD/CD-ROM,
1219*10452SAda.Feng@Sun.COM * no delay will be on resume.
1220*10452SAda.Feng@Sun.COM */
1221*10452SAda.Feng@Sun.COM if (need_wait == TRUE)
1222*10452SAda.Feng@Sun.COM drv_usecwait(5 * 100000);
12238550SSeth.Goldberg@Sun.COM ata_reset_dma_mode(ata_drvp);
12247787SAda.Feng@Sun.COM (void) atapi_id_update(ata_ctlp, ata_drvp, NULL);
12257787SAda.Feng@Sun.COM }
1226