11709Smlf /*
21709Smlf * CDDL HEADER START
31709Smlf *
41709Smlf * The contents of this file are subject to the terms of the
52799Smarx * 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 /*
23*8686SXun.Ni@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
241709Smlf * Use is subject to license terms.
251709Smlf */
261709Smlf
271709Smlf #include <sys/types.h>
281709Smlf #include <sys/dkio.h>
291709Smlf #include <sys/cdio.h>
301709Smlf #include <sys/file.h>
311709Smlf
321709Smlf #include "ata_common.h"
331709Smlf #include "ata_disk.h"
341709Smlf
351709Smlf /*
361709Smlf * this typedef really should be in dktp/cmpkt.h
371709Smlf */
381709Smlf typedef struct cmpkt cmpkt_t;
391709Smlf
401709Smlf
411709Smlf /*
421709Smlf * DADA entry points
431709Smlf */
441709Smlf
451709Smlf static int ata_disk_abort(opaque_t ctl_data, cmpkt_t *pktp);
461709Smlf static int ata_disk_reset(opaque_t ctl_data, int level);
471709Smlf static int ata_disk_ioctl(opaque_t ctl_data, int cmd, intptr_t a, int flag);
481709Smlf static cmpkt_t *ata_disk_pktalloc(opaque_t ctl_data, int (*callback)(caddr_t),
491709Smlf caddr_t arg);
501709Smlf static void ata_disk_pktfree(opaque_t ctl_data, cmpkt_t *pktp);
511709Smlf static cmpkt_t *ata_disk_memsetup(opaque_t ctl_data, cmpkt_t *pktp,
521709Smlf struct buf *bp, int (*callback)(caddr_t), caddr_t arg);
531709Smlf static void ata_disk_memfree(opaque_t ctl_data, cmpkt_t *pktp);
541709Smlf static cmpkt_t *ata_disk_iosetup(opaque_t ctl_data, cmpkt_t *pktp);
551709Smlf static int ata_disk_transport(opaque_t ctl_data, cmpkt_t *pktp);
561709Smlf
571709Smlf /*
581709Smlf * DADA packet callbacks
591709Smlf */
601709Smlf
611709Smlf static void ata_disk_complete(ata_drv_t *ata_drvp, ata_pkt_t *ata_pktp,
621709Smlf int do_callback);
631709Smlf static int ata_disk_intr(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
641709Smlf ata_pkt_t *ata_pktp);
651709Smlf static int ata_disk_intr_dma(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
661709Smlf ata_pkt_t *ata_pktp);
671709Smlf static int ata_disk_intr_pio_in(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
681709Smlf ata_pkt_t *ata_pktp);
691709Smlf static int ata_disk_intr_pio_out(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
701709Smlf ata_pkt_t *ata_pktp);
711709Smlf static int ata_disk_start(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
721709Smlf ata_pkt_t *ata_pktp);
731709Smlf static int ata_disk_start_dma_in(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
741709Smlf ata_pkt_t *ata_pktp);
751709Smlf static int ata_disk_start_dma_out(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
761709Smlf ata_pkt_t *ata_pktp);
771709Smlf static int ata_disk_start_pio_in(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
781709Smlf ata_pkt_t *ata_pktp);
791709Smlf static int ata_disk_start_pio_out(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
801709Smlf ata_pkt_t *ata_pktp);
811709Smlf
821709Smlf /*
831709Smlf * Local Function prototypes
841709Smlf */
851709Smlf
861709Smlf static int ata_disk_eject(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
871709Smlf ata_pkt_t *ata_pktp);
881709Smlf static void ata_disk_fake_inquiry(ata_drv_t *ata_drvp);
891709Smlf static void ata_disk_get_resid(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
901709Smlf ata_pkt_t *ata_pktp);
911709Smlf static int ata_disk_initialize_device_parameters(ata_ctl_t *ata_ctlp,
921709Smlf ata_drv_t *ata_drvp);
931709Smlf static int ata_disk_lock(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
941709Smlf ata_pkt_t *ata_pktp);
951709Smlf static int ata_disk_set_multiple(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp);
961709Smlf static void ata_disk_pio_xfer_data_in(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
971709Smlf static void ata_disk_pio_xfer_data_out(ata_ctl_t *ata_ctlp,
981709Smlf ata_pkt_t *ata_pktp);
991709Smlf static void ata_disk_set_standby_timer(ata_ctl_t *ata_ctlp,
1001709Smlf ata_drv_t *ata_drvp);
1011709Smlf static int ata_disk_recalibrate(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
1021709Smlf ata_pkt_t *ata_pktp);
1031709Smlf static int ata_disk_standby(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
1041709Smlf ata_pkt_t *ata_pktp);
1051709Smlf static int ata_disk_start_common(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
1061709Smlf ata_pkt_t *ata_pktp);
1071709Smlf static int ata_disk_state(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
1081709Smlf ata_pkt_t *ata_pktp);
1091709Smlf static int ata_disk_unlock(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
1101709Smlf ata_pkt_t *ata_pktp);
1111709Smlf static int ata_get_capacity(ata_drv_t *ata_drvp, uint64_t *capacity);
1121709Smlf static void ata_fix_large_disk_geometry(ata_drv_t *ata_drvp);
1131709Smlf static uint64_t ata_calculate_28bits_capacity(ata_drv_t *ata_drvp);
1141709Smlf static uint64_t ata_calculate_48bits_capacity(ata_drv_t *ata_drvp);
1151709Smlf static int ata_copy_dk_ioc_string(intptr_t arg, char *source, int length,
1161709Smlf int flag);
1171709Smlf static void ata_set_write_cache(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp);
1183652Syt160523 static int ata_disk_update_fw(gtgt_t *gtgtp, ata_ctl_t *ata_ctlp,
1193652Syt160523 ata_drv_t *ata_drvp, caddr_t fwfile, uint_t size,
1203652Syt160523 uint8_t type, int flag);
1213652Syt160523 static int ata_disk_set_feature_spinup(ata_ctl_t *ata_ctlp,
1223652Syt160523 ata_drv_t *ata_drvp, ata_pkt_t *ata_pktp);
1233652Syt160523 static int ata_disk_id_update(ata_ctl_t *ata_ctlp,
1243652Syt160523 ata_drv_t *ata_drvp, ata_pkt_t *ata_pktp);
1251709Smlf
1261709Smlf
1271709Smlf /*
1281709Smlf * Local static data
1291709Smlf */
1301709Smlf
1311709Smlf uint_t ata_disk_init_dev_parm_wait = 4 * 1000000;
1321709Smlf uint_t ata_disk_set_mult_wait = 4 * 1000000;
1331709Smlf int ata_disk_do_standby_timer = TRUE;
1341709Smlf
1353652Syt160523 /* timeout value for device update firmware */
1363652Syt160523 int ata_disk_updatefw_time = 60;
1373652Syt160523
1381709Smlf /*
1391709Smlf * ata_write_cache == 1 force write cache on.
1401709Smlf * ata_write_cache == 0 do not modify write cache. firmware defaults kept.
1411709Smlf * ata_write_cache == -1 force write cache off.
1421709Smlf */
1431709Smlf int ata_write_cache = 1;
1441709Smlf
1451709Smlf
1461709Smlf static struct ctl_objops ata_disk_objops = {
1471709Smlf ata_disk_pktalloc,
1481709Smlf ata_disk_pktfree,
1491709Smlf ata_disk_memsetup,
1501709Smlf ata_disk_memfree,
1511709Smlf ata_disk_iosetup,
1521709Smlf ata_disk_transport,
1531709Smlf ata_disk_reset,
1541709Smlf ata_disk_abort,
1551709Smlf nulldev,
1561709Smlf nulldev,
1571709Smlf ata_disk_ioctl,
1581709Smlf 0, 0
1591709Smlf };
1601709Smlf
1611709Smlf
1621709Smlf
1631709Smlf /*
1641709Smlf *
1651709Smlf * initialize the ata_disk sub-system
1661709Smlf *
1671709Smlf */
1681709Smlf
1691709Smlf /*ARGSUSED*/
1701709Smlf int
ata_disk_attach(ata_ctl_t * ata_ctlp)1711709Smlf ata_disk_attach(
1721709Smlf ata_ctl_t *ata_ctlp)
1731709Smlf {
1741709Smlf ADBG_TRACE(("ata_disk_init entered\n"));
1751709Smlf return (TRUE);
1761709Smlf }
1771709Smlf
1781709Smlf
1791709Smlf
1801709Smlf /*
1811709Smlf *
1821709Smlf * destroy the ata_disk sub-system
1831709Smlf *
1841709Smlf */
1851709Smlf
1861709Smlf /*ARGSUSED*/
1871709Smlf void
ata_disk_detach(ata_ctl_t * ata_ctlp)1881709Smlf ata_disk_detach(
1891709Smlf ata_ctl_t *ata_ctlp)
1901709Smlf {
1911709Smlf ADBG_TRACE(("ata_disk_destroy entered\n"));
1921709Smlf }
1931709Smlf
1941709Smlf
1951709Smlf /*
1961709Smlf * Test whether the disk can support Logical Block Addressing
1971709Smlf */
1981709Smlf
1991709Smlf int
ata_test_lba_support(struct ata_id * aidp)2001709Smlf ata_test_lba_support(struct ata_id *aidp)
2011709Smlf {
2021709Smlf #ifdef __old_version__
2031709Smlf /*
2041709Smlf * determine if the drive supports LBA mode
2051709Smlf */
2061709Smlf if (aidp->ai_cap & ATAC_LBA_SUPPORT)
2071709Smlf return (TRUE);
2081709Smlf #else
2091709Smlf /*
2101709Smlf * Determine if the drive supports LBA mode
2111709Smlf * LBA mode is mandatory on ATA-3 (or newer) drives but is
2121709Smlf * optional on ATA-2 (or older) drives. On ATA-2 drives
2131709Smlf * the ai_majorversion word should be 0xffff or 0x0000
2141709Smlf * (version not reported).
2151709Smlf */
2161709Smlf if (aidp->ai_majorversion != 0xffff &&
2171709Smlf aidp->ai_majorversion >= (1 << 3)) {
2181709Smlf /* ATA-3 or better */
2191709Smlf return (TRUE);
2201709Smlf } else if (aidp->ai_cap & ATAC_LBA_SUPPORT) {
2211709Smlf /* ATA-2 LBA capability bit set */
2221709Smlf return (TRUE);
2231709Smlf } else {
2241709Smlf return (FALSE);
2251709Smlf }
2261709Smlf #endif
2271709Smlf }
2281709Smlf
2291709Smlf /*
2301709Smlf * ATA-6 drives do not provide geometry information, so words
2311709Smlf * ai_heads, ai_sectors and ai_fixcyls may not be valid
2321709Smlf */
2331709Smlf static void
ata_fixup_ata6_geometry(struct ata_id * aidp)2341709Smlf ata_fixup_ata6_geometry(struct ata_id *aidp)
2351709Smlf {
2361709Smlf /* check cylinders, heads, and sectors for valid values */
2371709Smlf if (aidp->ai_heads != 0 && aidp->ai_heads != 0xffff &&
2381709Smlf aidp->ai_sectors != 0 && aidp->ai_sectors != 0xffff &&
2391709Smlf aidp->ai_fixcyls != 0)
2401709Smlf return; /* assume valid geometry - do nothing */
2411709Smlf
2421709Smlf /*
2431709Smlf * Pre-set standard geometry values - they are not necessarily
2441709Smlf * optimal for a given capacity
2451709Smlf */
2461709Smlf aidp->ai_heads = 0x10;
2471709Smlf aidp->ai_sectors = 0x3f;
2481709Smlf aidp->ai_fixcyls = 1;
2491709Smlf /*
2501709Smlf * The fixcyls value will get fixed up later in
2511709Smlf * ata_fix_large_disk_geometry.
2521709Smlf */
2531709Smlf }
2541709Smlf
2551709Smlf /*
2561709Smlf *
2571709Smlf * initialize the soft-structure for an ATA (non-PACKET) drive and
2581709Smlf * then configure the drive with the correct modes and options.
2591709Smlf *
2601709Smlf */
2611709Smlf
2621709Smlf int
ata_disk_init_drive(ata_drv_t * ata_drvp)2631709Smlf ata_disk_init_drive(
2641709Smlf ata_drv_t *ata_drvp)
2651709Smlf {
2661709Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
2671709Smlf struct ata_id *aidp = &ata_drvp->ad_id;
2681709Smlf struct ctl_obj *ctlobjp;
2691709Smlf struct scsi_device *devp;
2701709Smlf int len;
2711709Smlf int val;
2721709Smlf int mode;
2731709Smlf short *chs;
2741709Smlf char buf[80];
2751709Smlf
2761709Smlf ADBG_TRACE(("ata_disk_init_drive entered\n"));
2771709Smlf
2781709Smlf /* ATA disks don't support LUNs */
2791709Smlf
2801709Smlf if (ata_drvp->ad_lun != 0)
2811709Smlf return (FALSE);
2821709Smlf
2831709Smlf /*
2841709Smlf * set up drive structure
2851709Smlf * ATA-6 drives do not provide geometry information, so words
2861709Smlf * ai_heads, ai_sectors and ai_fixcyls may not be valid - they
2871709Smlf * will be fixed later
2881709Smlf */
2891709Smlf
2901709Smlf ata_drvp->ad_phhd = aidp->ai_heads;
2911709Smlf ata_drvp->ad_phsec = aidp->ai_sectors;
2921709Smlf ata_drvp->ad_drvrhd = aidp->ai_heads;
2931709Smlf ata_drvp->ad_drvrsec = aidp->ai_sectors;
2941709Smlf ata_drvp->ad_drvrcyl = aidp->ai_fixcyls;
2951709Smlf ata_drvp->ad_acyl = 0;
2961709Smlf
2971709Smlf if (ata_test_lba_support(&ata_drvp->ad_id))
2981709Smlf ata_drvp->ad_drive_bits |= ATDH_LBA;
2991709Smlf
3001709Smlf /* Get capacity and check for 48-bit mode */
3011709Smlf mode = ata_get_capacity(ata_drvp, &ata_drvp->ad_capacity);
3021709Smlf if (mode == AD_EXT48) {
3031709Smlf ata_drvp->ad_flags |= AD_EXT48;
3041709Smlf }
3051709Smlf
3061709Smlf /* straighten out the geometry */
3071709Smlf (void) sprintf(buf, "SUNW-ata-%p-d%d-chs", (void *) ata_ctlp->ac_data,
3081709Smlf ata_drvp->ad_targ+1);
3091709Smlf if (ddi_getlongprop(DDI_DEV_T_ANY, ddi_root_node(), 0,
3101709Smlf buf, (caddr_t)&chs, &len) == DDI_PROP_SUCCESS) {
3111709Smlf /*
3121709Smlf * if the number of sectors and heads in bios matches the
3131709Smlf * physical geometry, then so should the number of cylinders
3141709Smlf * this is to prevent the 1023 limit in the older bios's
3151709Smlf * causing loss of space.
3161709Smlf */
3171709Smlf if (chs[1] == (ata_drvp->ad_drvrhd - 1) &&
3181709Smlf chs[2] == ata_drvp->ad_drvrsec)
3191709Smlf /* Set chs[0] to zero-based number of cylinders. */
3201709Smlf chs[0] = aidp->ai_fixcyls - 1;
3211709Smlf else if (!(ata_drvp->ad_drive_bits & ATDH_LBA)) {
3221709Smlf /*
3231709Smlf * if the the sector/heads do not match that of the
3241709Smlf * bios and the drive does not support LBA. We go ahead
3251709Smlf * and advertise the bios geometry but use the physical
3261709Smlf * geometry for sector translation.
3271709Smlf */
3281709Smlf cmn_err(CE_WARN, "!Disk 0x%p,%d: BIOS geometry "
3291709Smlf "different from physical, and no LBA support.",
3301709Smlf (void *)ata_ctlp->ac_data, ata_drvp->ad_targ);
3311709Smlf }
3321709Smlf
3331709Smlf /*
3341709Smlf * chs[0,1] are zero-based; make them one-based.
3351709Smlf */
3361709Smlf ata_drvp->ad_drvrcyl = chs[0] + 1;
3371709Smlf ata_drvp->ad_drvrhd = chs[1] + 1;
3381709Smlf ata_drvp->ad_drvrsec = chs[2];
3391709Smlf kmem_free(chs, len);
3401709Smlf } else {
3411709Smlf /*
3421709Smlf * Property not present; this means that boot.bin has
3431709Smlf * determined that the drive supports Int13 LBA. Note
3441709Smlf * this, but just return a geometry with a large
3451709Smlf * cylinder count; this will be the signal for dadk to
3461709Smlf * fail DKIOCG_VIRTGEOM.
3471709Smlf * ad_drvr* are already set; just recalculate ad_drvrcyl
3481709Smlf * from capacity.
3491709Smlf */
3501709Smlf
3511709Smlf ata_drvp->ad_flags |= AD_INT13LBA;
3521709Smlf if (ata_drvp->ad_capacity != 0) {
3531709Smlf ata_drvp->ad_drvrcyl = ata_drvp->ad_capacity /
3541709Smlf (ata_drvp->ad_drvrhd * ata_drvp->ad_drvrsec);
3551709Smlf } else {
3561709Smlf /*
3571709Smlf * Something's wrong; return something sure to
3581709Smlf * fail the "cyls < 1024" test. This will
3591709Smlf * never make it out of the DKIOCG_VIRTGEOM
3601709Smlf * call, so its total bogosity won't matter.
3611709Smlf */
3621709Smlf ata_drvp->ad_drvrcyl = 1025;
3631709Smlf ata_drvp->ad_drvrhd = 1;
3641709Smlf ata_drvp->ad_drvrsec = 1;
3651709Smlf }
3661709Smlf }
3671709Smlf
3681709Smlf /* fix geometry for disks > 31GB, if needed */
3691709Smlf ata_fix_large_disk_geometry(ata_drvp);
3701709Smlf
3711709Smlf /*
3721709Smlf * set up the scsi_device and ctl_obj structures
3731709Smlf */
3746640Scth devp = kmem_zalloc(scsi_device_size(), KM_SLEEP);
3756640Scth ata_drvp->ad_device = devp;
3761709Smlf ctlobjp = &ata_drvp->ad_ctl_obj;
3771709Smlf
3781709Smlf devp->sd_inq = &ata_drvp->ad_inquiry;
3791709Smlf devp->sd_address.a_hba_tran = (scsi_hba_tran_t *)ctlobjp;
3801709Smlf devp->sd_address.a_target = (ushort_t)ata_drvp->ad_targ;
3811709Smlf devp->sd_address.a_lun = (uchar_t)ata_drvp->ad_lun;
3821709Smlf mutex_init(&devp->sd_mutex, NULL, MUTEX_DRIVER, NULL);
3831709Smlf ata_drvp->ad_flags |= AD_MUTEX_INIT;
3841709Smlf
3851709Smlf /*
3861709Smlf * DADA ops vectors and cookie
3871709Smlf */
3881709Smlf ctlobjp->c_ops = (struct ctl_objops *)&ata_disk_objops;
3891709Smlf
3901709Smlf /*
3911709Smlf * this is filled in with gtgtp by ata_disk_bus_ctl(INITCHILD)
3921709Smlf */
3931709Smlf ctlobjp->c_data = NULL;
3941709Smlf
3951709Smlf ctlobjp->c_ext = &(ctlobjp->c_extblk);
3961709Smlf ctlobjp->c_extblk.c_ctldip = ata_ctlp->ac_dip;
3971709Smlf ctlobjp->c_extblk.c_targ = ata_drvp->ad_targ;
3981709Smlf ctlobjp->c_extblk.c_blksz = NBPSCTR;
3991709Smlf
4001709Smlf /*
4011709Smlf * Get highest block factor supported by the drive.
4021709Smlf * Some drives report 0 if read/write multiple not supported,
4031709Smlf * adjust their blocking factor to 1.
4041709Smlf */
4051709Smlf ata_drvp->ad_block_factor = aidp->ai_mult1 & 0xff;
4061709Smlf
4071709Smlf /*
4081709Smlf * If a block factor property exists, use the smaller of the
4091709Smlf * property value and the highest value the drive can support.
4101709Smlf */
4111709Smlf (void) sprintf(buf, "drive%d_block_factor", ata_drvp->ad_targ);
4121709Smlf val = ddi_prop_get_int(DDI_DEV_T_ANY, ata_ctlp->ac_dip, 0, buf,
4131709Smlf ata_drvp->ad_block_factor);
4141709Smlf
4151709Smlf ata_drvp->ad_block_factor = (short)min(val, ata_drvp->ad_block_factor);
4161709Smlf
4171709Smlf if (ata_drvp->ad_block_factor == 0)
4181709Smlf ata_drvp->ad_block_factor = 1;
4191709Smlf
4206640Scth if (!ata_disk_setup_parms(ata_ctlp, ata_drvp)) {
4216640Scth ata_drvp->ad_device = NULL;
4226640Scth kmem_free(devp, scsi_device_size());
4231709Smlf return (FALSE);
4246640Scth }
4251709Smlf
4261709Smlf ata_disk_fake_inquiry(ata_drvp);
4271709Smlf
4281709Smlf return (TRUE);
4291709Smlf }
4301709Smlf
4311709Smlf /*
4321709Smlf * Test if a disk supports 48-bit (extended mode) addressing and
4331709Smlf * get disk capacity.
4341709Smlf * Return value:
4351709Smlf * AD_EXT48 if 48-bit mode is available, 0 otherwise,
4361709Smlf * capacity in sectors.
4371709Smlf * There are several indicators for 48-bit addressing. If any of
4381709Smlf * them is missing, assume 28-bit (non-extended) addressing.
4391709Smlf */
4401709Smlf
4411709Smlf static int
ata_get_capacity(ata_drv_t * ata_drvp,uint64_t * capacity)4421709Smlf ata_get_capacity(ata_drv_t *ata_drvp, uint64_t *capacity)
4431709Smlf {
4441709Smlf struct ata_id *aidp = &ata_drvp->ad_id;
4451709Smlf uint64_t cap28; /* capacity in 28-bit mode */
4461709Smlf uint64_t cap48; /* capacity in 48-bit mode */
4471709Smlf
4481709Smlf /*
4491709Smlf * First compute capacity in 28-bit mode, using 28-bit capacity
4501709Smlf * words in IDENTIFY DEVICE response words
4511709Smlf */
4521709Smlf cap28 = ata_calculate_28bits_capacity(ata_drvp);
4531709Smlf *capacity = cap28;
4541709Smlf
4557963SColin.Yi@Sun.COM if (!IS_ATA_VERSION_SUPPORTED(aidp, 6) &&
4567963SColin.Yi@Sun.COM !(ata_drvp->ad_flags & AD_BLLBA48))
4571709Smlf return (0);
4581709Smlf
4591709Smlf /* Check that 48 bit addressing is supported & enabled */
4601709Smlf /* words 83 and 86 */
4611709Smlf if (!(aidp->ai_cmdset83 & ATACS_EXT48))
4621709Smlf return (0);
4631709Smlf if (!(aidp->ai_features86 & ATACS_EXT48))
4641709Smlf return (0);
4651709Smlf
4661709Smlf /*
4671709Smlf * Drive supports ATA-6. Since ATA-6 drives may not provide
4681709Smlf * geometry info, pre-set standard geometry values
4691709Smlf */
4701709Smlf ata_fixup_ata6_geometry(aidp);
4711709Smlf
4721709Smlf /* Compute 48-bit capacity */
4731709Smlf cap48 = ata_calculate_48bits_capacity(ata_drvp);
4741709Smlf
4751709Smlf /*
4761709Smlf * If capacity is smaller then the maximum capacity addressable
4771709Smlf * in 28-bit mode, just use 28-bit capacity value.
4781709Smlf * We will use 28-bit addressing read/write commands.
4791709Smlf */
4801709Smlf if (cap48 <= MAX_28BIT_CAPACITY)
4811709Smlf return (0);
4821709Smlf
4831709Smlf /*
4841709Smlf * Capacity is too big for 28-bits addressing. But, to make
4851709Smlf * sure that the drive implements ATA-6 correctly, the
4861709Smlf * final check: cap28 should be MAX for 28-bit addressing.
4871709Smlf * If it's not, we shouldn't use 48-bit mode, so return
4881709Smlf * the capacity reported in 28-bit capacity words.
4891709Smlf */
4901709Smlf if (cap28 != MAX_28BIT_CAPACITY)
4911709Smlf return (0); /* not max, use 28-bit value */
4921709Smlf
4931709Smlf /*
4941709Smlf * All is well so return 48-bit capacity indicator
4951709Smlf */
4961709Smlf ADBG_INIT(("ATA: using 48-bit mode for capacity %llx blocks\n",
4971709Smlf (unsigned long long)cap48));
4981709Smlf
4991709Smlf *capacity = cap48;
5001709Smlf return (AD_EXT48);
5011709Smlf }
5021709Smlf
5031709Smlf /*
5041709Smlf * With the advent of disks that hold more than 31 GB, we run into a
5051709Smlf * limitation in the sizes of the fields that describe the geometry.
5061709Smlf * The cylinders, heads, and sectors-per-track are each described by a
5071709Smlf * 16-bit number -- both in the structure returned from IDENTIFY
5081709Smlf * DEVICE and in the structure returned from the DIOCTL_GETGEOM or
5091709Smlf * DIOCTL_GETPHYGEOM ioctl.
5101709Smlf *
5111709Smlf * The typical disk has 32 heads per cylinder and 63 sectors per
5121709Smlf * track. A 16 bit field can contain up to 65535. So the largest
5131709Smlf * disk that can be described in these fields is 65535 * 32 * 63 * 512
5141709Smlf * (bytes/sector), or about 31.5 GB. The cylinder count gets truncated
5151709Smlf * when stored in a narrow field, so a 40GB disk appears to have only
5161709Smlf * 8 GB!
5171709Smlf *
5181709Smlf * The solution (for the time being at least) is to lie about the
5191709Smlf * geometry. If the number of cylinders is too large to fit in 16
5201709Smlf * bits, we will halve the cylinders and double the heads, repeating
5211709Smlf * until we can fit the geometry into 3 shorts.
5221709Smlf * FUTURE ENHANCEMENT: If this ever isn't enough, we could
5231709Smlf * add another step to double sectors/track as well.
5241709Smlf */
5251709Smlf
5261709Smlf static void
ata_fix_large_disk_geometry(ata_drv_t * ata_drvp)5271709Smlf ata_fix_large_disk_geometry(
5281709Smlf ata_drv_t *ata_drvp)
5291709Smlf {
5301709Smlf struct ata_id *aidp = &ata_drvp->ad_id;
5311709Smlf
5321709Smlf /* no hope for large disks if LBA not supported */
5331709Smlf if (!(ata_drvp->ad_drive_bits & ATDH_LBA))
5341709Smlf return;
5351709Smlf
5361709Smlf /*
5371709Smlf * Fix up the geometry to be returned by DIOCTL_GETGEOM.
5381709Smlf * If number of cylinders > USHRT_MAX, double heads and
5391709Smlf * halve cylinders until everything fits.
5401709Smlf */
5411709Smlf while (ata_drvp->ad_drvrcyl > USHRT_MAX) {
5421709Smlf int tempheads;
5431709Smlf
5441709Smlf /* is there room in 16 bits to double the heads? */
5451709Smlf tempheads = 2 * ata_drvp->ad_drvrhd;
5461709Smlf if (tempheads > USHRT_MAX) {
5471709Smlf /*
5481709Smlf * No room to double the heads.
5491709Smlf * I give up, there's no way to represent this.
5501709Smlf * Limit disk size.
5511709Smlf */
5521709Smlf cmn_err(CE_WARN,
5531709Smlf "Disk is too large: "
5541709Smlf "Model %s, Serial# %s "
5551709Smlf "Approximating...\n",
5561709Smlf aidp->ai_model, aidp->ai_drvser);
5571709Smlf ata_drvp->ad_drvrcyl = USHRT_MAX;
5581709Smlf break;
5591709Smlf }
5601709Smlf
5611709Smlf /* OK, so double the heads and halve the cylinders */
5621709Smlf ata_drvp->ad_drvrcyl /= 2;
5631709Smlf ata_drvp->ad_drvrhd *= 2;
5641709Smlf }
5651709Smlf }
5661709Smlf
5671709Smlf /*
5681709Smlf * Calculate capacity using 28-bit capacity words from IDENTIFY DEVICE
5691709Smlf * return words
5701709Smlf */
5711709Smlf uint64_t
ata_calculate_28bits_capacity(ata_drv_t * ata_drvp)5721709Smlf ata_calculate_28bits_capacity(ata_drv_t *ata_drvp)
5731709Smlf {
5741709Smlf /*
5751709Smlf * Asked x3t13 for advice; this implements Hale Landis'
5761709Smlf * response, minus the "use ATA_INIT_DEVPARMS".
5771709Smlf * See "capacity.notes".
5781709Smlf */
5791709Smlf
5801709Smlf /* some local shorthand/renaming to clarify the meaning */
5811709Smlf
5821709Smlf ushort_t curcyls_w54, curhds_w55, cursect_w56;
5831709Smlf uint32_t curcap_w57_58;
5841709Smlf
5851709Smlf if ((ata_drvp->ad_drive_bits & ATDH_LBA) != 0) {
5861709Smlf return ((uint64_t)(ata_drvp->ad_id.ai_addrsec[0] +
5871709Smlf ata_drvp->ad_id.ai_addrsec[1] * 0x10000));
5881709Smlf }
5891709Smlf
5901709Smlf /*
5911709Smlf * If we're not LBA, then first try to validate "current" values.
5921709Smlf */
5931709Smlf
5941709Smlf curcyls_w54 = ata_drvp->ad_id.ai_curcyls;
5951709Smlf curhds_w55 = ata_drvp->ad_id.ai_curheads;
5961709Smlf cursect_w56 = ata_drvp->ad_id.ai_cursectrk;
5971709Smlf curcap_w57_58 = ata_drvp->ad_id.ai_cursccp[0] +
5981709Smlf ata_drvp->ad_id.ai_cursccp[1] * 0x10000;
5991709Smlf
6001709Smlf if (((ata_drvp->ad_id.ai_validinfo & 1) == 1) &&
6011709Smlf (curhds_w55 >= 1) && (curhds_w55 <= 16) &&
6021709Smlf (cursect_w56 >= 1) && (cursect_w56 <= 63) &&
6031709Smlf (curcap_w57_58 == curcyls_w54 * curhds_w55 * cursect_w56)) {
6041709Smlf return ((uint64_t)curcap_w57_58);
6051709Smlf }
6061709Smlf
6071709Smlf /*
6081709Smlf * At this point, Hale recommends ATA_INIT_DEVPARMS.
6091709Smlf * I don't want to do that, so simply use 1/3/6 as
6101709Smlf * a final fallback, and continue to assume the BIOS
6111709Smlf * has done whatever INIT_DEVPARMS are necessary.
6121709Smlf */
6131709Smlf
6141709Smlf return ((uint64_t)(ata_drvp->ad_id.ai_fixcyls *
6151709Smlf ata_drvp->ad_id.ai_heads * ata_drvp->ad_id.ai_sectors));
6161709Smlf }
6171709Smlf
6181709Smlf /*
6191709Smlf * Calculate capacity using 48-bits capacity words from IDENTIFY DEVICE
6201709Smlf * return words
6211709Smlf */
6221709Smlf uint64_t
ata_calculate_48bits_capacity(ata_drv_t * ata_drvp)6231709Smlf ata_calculate_48bits_capacity(ata_drv_t *ata_drvp)
6241709Smlf {
6251709Smlf uint64_t cap48 = 0;
6261709Smlf int i;
6271709Smlf
6281709Smlf for (i = 3; i >= 0; --i) {
6291709Smlf cap48 <<= 16;
6301709Smlf cap48 += ata_drvp->ad_id.ai_addrsecxt[i];
6311709Smlf }
6321709Smlf return (cap48);
6331709Smlf }
6341709Smlf
6351709Smlf
6361709Smlf /*
6371709Smlf *
6381709Smlf * Setup the drives Read/Write Multiple Blocking factor and the
6391709Smlf * current translation geometry. Necessary during attach and after
6401709Smlf * Software Resets.
6411709Smlf *
6421709Smlf */
6431709Smlf
6441709Smlf int
ata_disk_setup_parms(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp)6451709Smlf ata_disk_setup_parms(
6461709Smlf ata_ctl_t *ata_ctlp,
6471709Smlf ata_drv_t *ata_drvp)
6481709Smlf {
6491709Smlf
6501709Smlf /*
6511709Smlf * program geometry info back to the drive
6521709Smlf */
6531709Smlf if (!ata_disk_initialize_device_parameters(ata_ctlp, ata_drvp)) {
6541709Smlf return (FALSE);
6551709Smlf }
6561709Smlf
6571709Smlf /*
6581709Smlf * Determine the blocking factor
6591709Smlf */
6601709Smlf if (ata_drvp->ad_block_factor > 1) {
6611709Smlf /*
6621709Smlf * Program the block factor into the drive. If this
6631709Smlf * fails, then go back to using a block size of 1.
6641709Smlf */
6651709Smlf if (!ata_disk_set_multiple(ata_ctlp, ata_drvp))
6661709Smlf ata_drvp->ad_block_factor = 1;
6671709Smlf }
6681709Smlf
6691709Smlf
6701709Smlf if (ata_drvp->ad_block_factor > 1) {
6711709Smlf ata_drvp->ad_rd_cmd = ATC_RDMULT;
6721709Smlf ata_drvp->ad_wr_cmd = ATC_WRMULT;
6731709Smlf } else {
6741709Smlf ata_drvp->ad_rd_cmd = ATC_RDSEC;
6751709Smlf ata_drvp->ad_wr_cmd = ATC_WRSEC;
6761709Smlf }
6771709Smlf
6781709Smlf ata_drvp->ad_bytes_per_block = ata_drvp->ad_block_factor << SCTRSHFT;
6791709Smlf
6801709Smlf ADBG_INIT(("set block factor for drive %d to %d\n",
6811709Smlf ata_drvp->ad_targ, ata_drvp->ad_block_factor));
6821709Smlf
6831709Smlf if (ata_disk_do_standby_timer)
6841709Smlf ata_disk_set_standby_timer(ata_ctlp, ata_drvp);
6851709Smlf
6861709Smlf ata_set_write_cache(ata_ctlp, ata_drvp);
6871709Smlf
6881709Smlf return (TRUE);
6891709Smlf }
6901709Smlf
6911709Smlf
6921709Smlf /*
6931709Smlf * Take the timeout value specified in the "standby" property
6941709Smlf * and convert from seconds to the magic parm expected by the
6951709Smlf * the drive. Then issue the IDLE command to set the drive's
6961709Smlf * internal standby timer.
6971709Smlf */
6981709Smlf
6991709Smlf static void
ata_disk_set_standby_timer(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp)7001709Smlf ata_disk_set_standby_timer(
7011709Smlf ata_ctl_t *ata_ctlp,
7021709Smlf ata_drv_t *ata_drvp)
7031709Smlf {
7041709Smlf uchar_t parm;
7051709Smlf int timeout = ata_ctlp->ac_standby_time;
7061709Smlf
7071709Smlf /*
7081709Smlf * take the timeout value, specificed in seconds, and
7091709Smlf * encode it into the proper command parm
7101709Smlf */
7111709Smlf
7121709Smlf /*
7131709Smlf * don't change it if no property specified or if
7141709Smlf * the specified value is out of range
7151709Smlf */
7161709Smlf if (timeout < 0 || timeout > (12 * 60 * 60))
7171709Smlf return;
7181709Smlf
7191709Smlf /* 1 to 1200 seconds (20 minutes) == N * 5 seconds */
7201709Smlf if (timeout <= (240 * 5))
7211709Smlf parm = (timeout + 4) / 5;
7221709Smlf
7231709Smlf /* 20 to 21 minutes == 21 minutes */
7241709Smlf else if (timeout <= (21 * 60))
7251709Smlf parm = 252;
7261709Smlf
7271709Smlf /* 21 minutes to 21 minutes 15 seconds == 21:15 */
7281709Smlf else if (timeout <= ((21 * 60) + 15))
7291709Smlf parm = 255;
7301709Smlf
7311709Smlf /* 21:15 to 330 minutes == N * 30 minutes */
7321709Smlf else if (timeout <= (11 * 30 * 60))
7331709Smlf parm = 240 + ((timeout + (30 * 60) - 1)/ (30 * 60));
7341709Smlf
7351709Smlf /* > 330 minutes == 8 to 12 hours */
7361709Smlf else
7371709Smlf parm = 253;
7381709Smlf
7391709Smlf (void) ata_command(ata_ctlp, ata_drvp, TRUE, FALSE, 5 * 1000000,
7401709Smlf ATC_IDLE, 0, parm, 0, 0, 0, 0);
7411709Smlf }
7421709Smlf
7431709Smlf
7441709Smlf
7451709Smlf /*
7461709Smlf *
7471709Smlf * destroy an ata disk drive
7481709Smlf *
7491709Smlf */
7501709Smlf
7511709Smlf void
ata_disk_uninit_drive(ata_drv_t * ata_drvp)7521709Smlf ata_disk_uninit_drive(
7531709Smlf ata_drv_t *ata_drvp)
7541709Smlf {
7556640Scth struct scsi_device *devp = ata_drvp->ad_device;
7561709Smlf
7571709Smlf ADBG_TRACE(("ata_disk_uninit_drive entered\n"));
7581709Smlf
7596640Scth if (devp) {
7606640Scth if (ata_drvp->ad_flags & AD_MUTEX_INIT)
7616640Scth mutex_destroy(&devp->sd_mutex);
7626640Scth ata_drvp->ad_device = NULL;
7636640Scth kmem_free(devp, scsi_device_size());
7646640Scth }
7651709Smlf }
7661709Smlf
7671709Smlf
7681709Smlf
7691709Smlf
7701709Smlf /*
7711709Smlf *
7721709Smlf * DADA compliant bus_ctl entry point
7731709Smlf *
7741709Smlf */
7751709Smlf
7761709Smlf /*ARGSUSED*/
7771709Smlf int
ata_disk_bus_ctl(dev_info_t * d,dev_info_t * r,ddi_ctl_enum_t o,void * a,void * v)7781709Smlf ata_disk_bus_ctl(
7791709Smlf dev_info_t *d,
7801709Smlf dev_info_t *r,
7811709Smlf ddi_ctl_enum_t o,
7821709Smlf void *a,
7831709Smlf void *v)
7841709Smlf {
7851709Smlf ADBG_TRACE(("ata_disk_bus_ctl entered\n"));
7861709Smlf
7871709Smlf switch (o) {
7881709Smlf
7891709Smlf case DDI_CTLOPS_REPORTDEV:
7901709Smlf {
7911709Smlf int targ;
7921709Smlf
7931709Smlf targ = ddi_prop_get_int(DDI_DEV_T_ANY, r, DDI_PROP_DONTPASS,
7941709Smlf "target", 0);
7951709Smlf cmn_err(CE_CONT, "?%s%d at %s%d target %d lun %d\n",
7961709Smlf ddi_driver_name(r), ddi_get_instance(r),
7971709Smlf ddi_driver_name(d), ddi_get_instance(d), targ, 0);
7981709Smlf return (DDI_SUCCESS);
7991709Smlf }
8001709Smlf case DDI_CTLOPS_INITCHILD:
8011709Smlf {
8021709Smlf dev_info_t *cdip = (dev_info_t *)a;
8031709Smlf ata_drv_t *ata_drvp;
8041709Smlf ata_ctl_t *ata_ctlp;
8051709Smlf ata_tgt_t *ata_tgtp;
8061709Smlf struct scsi_device *devp;
8071709Smlf struct ctl_obj *ctlobjp;
8081709Smlf gtgt_t *gtgtp;
8091709Smlf char name[MAXNAMELEN];
8101709Smlf
8111709Smlf /*
8121709Smlf * save time by picking up ptr to drive struct left
8131709Smlf * by ata_bus_ctl - isn't that convenient.
8141709Smlf */
8151709Smlf ata_drvp = ddi_get_driver_private(cdip);
8161709Smlf ata_ctlp = ata_drvp->ad_ctlp;
8171709Smlf
8181709Smlf /* set up pointers to child dip */
8191709Smlf
8206640Scth devp = ata_drvp->ad_device;
8211709Smlf /*
8221709Smlf * If sd_dev is set, it means that the target has already
8231709Smlf * being initialized. The cdip is a duplicate node from
8241709Smlf * reexpansion of driver.conf. Fail INITCHILD here.
8251709Smlf */
8266640Scth if ((devp == NULL) || (devp->sd_dev != NULL)) {
8271709Smlf return (DDI_FAILURE);
8281709Smlf }
8291709Smlf devp->sd_dev = cdip;
8301709Smlf
8311709Smlf ctlobjp = &ata_drvp->ad_ctl_obj;
8321709Smlf ctlobjp->c_extblk.c_devdip = cdip;
8331709Smlf
8341709Smlf /*
8351709Smlf * Create the "ata" property for use by the target driver
8361709Smlf */
8371709Smlf if (!ata_prop_create(cdip, ata_drvp, "ata")) {
8381709Smlf return (DDI_FAILURE);
8391709Smlf }
8401709Smlf
8411709Smlf gtgtp = ghd_target_init(d, cdip, &ata_ctlp->ac_ccc,
8421709Smlf sizeof (ata_tgt_t), ata_ctlp,
8431709Smlf ata_drvp->ad_targ,
8441709Smlf ata_drvp->ad_lun);
8451709Smlf
8461709Smlf /* gt_tgt_private points to ata_tgt_t */
8471709Smlf ata_tgtp = GTGTP2ATATGTP(gtgtp);
8481709Smlf ata_tgtp->at_drvp = ata_drvp;
8491709Smlf ata_tgtp->at_dma_attr = ata_pciide_dma_attr;
8501709Smlf ata_tgtp->at_dma_attr.dma_attr_maxxfer =
8511709Smlf ata_ctlp->ac_max_transfer << SCTRSHFT;
8521709Smlf
8531709Smlf /* gtgtp is the opaque arg to all my entry points */
8541709Smlf ctlobjp->c_data = gtgtp;
8551709Smlf
8561709Smlf /* create device name */
8571709Smlf
8581709Smlf (void) sprintf(name, "%x,%x", ata_drvp->ad_targ,
8591709Smlf ata_drvp->ad_lun);
8601709Smlf ddi_set_name_addr(cdip, name);
8611709Smlf ddi_set_driver_private(cdip, devp);
8621709Smlf
8631709Smlf return (DDI_SUCCESS);
8641709Smlf }
8651709Smlf
8661709Smlf case DDI_CTLOPS_UNINITCHILD:
8671709Smlf {
8681709Smlf dev_info_t *cdip = (dev_info_t *)a;
8691709Smlf struct scsi_device *devp;
8701709Smlf struct ctl_obj *ctlobjp;
8711709Smlf gtgt_t *gtgtp;
8721709Smlf
8731709Smlf devp = ddi_get_driver_private(cdip);
8741709Smlf ctlobjp = (struct ctl_obj *)devp->sd_address.a_hba_tran;
8751709Smlf gtgtp = ctlobjp->c_data;
8761709Smlf
8771709Smlf ghd_target_free(d, cdip, >GTP2ATAP(gtgtp)->ac_ccc, gtgtp);
8781709Smlf
8791709Smlf ddi_set_driver_private(cdip, NULL);
8801709Smlf ddi_set_name_addr(cdip, NULL);
8811709Smlf return (DDI_SUCCESS);
8821709Smlf }
8831709Smlf
8841709Smlf default:
8851709Smlf return (DDI_FAILURE);
8861709Smlf }
8871709Smlf }
8881709Smlf
8891709Smlf
8901709Smlf /*
8911709Smlf *
8921709Smlf * DADA abort entry point - not currently used by dadk
8931709Smlf *
8941709Smlf */
8951709Smlf
8961709Smlf /* ARGSUSED */
8971709Smlf static int
ata_disk_abort(opaque_t ctl_data,cmpkt_t * pktp)8981709Smlf ata_disk_abort(opaque_t ctl_data, cmpkt_t *pktp)
8991709Smlf {
9001709Smlf ADBG_TRACE(("ata_disk_abort entered\n"));
9011709Smlf
9021709Smlf /* XXX - Note that this interface is currently not used by dadk */
9031709Smlf
9041709Smlf /*
9051709Smlf * GHD abort functions take a pointer to a scsi_address
9061709Smlf * and so they're unusable here. The ata driver used to
9071709Smlf * return DDI_SUCCESS here without doing anything. Its
9081709Smlf * seems that DDI_FAILURE is more appropriate.
9091709Smlf */
9101709Smlf
9111709Smlf return (DDI_FAILURE);
9121709Smlf }
9131709Smlf
9141709Smlf
9151709Smlf
9161709Smlf /*
9171709Smlf *
9181709Smlf * DADA reset entry point - not currently used by dadk
9191709Smlf * (except in debug versions of driver)
9201709Smlf *
9211709Smlf */
9221709Smlf
9231709Smlf /* ARGSUSED */
9241709Smlf static int
ata_disk_reset(opaque_t ctl_data,int level)9251709Smlf ata_disk_reset(opaque_t ctl_data, int level)
9261709Smlf {
9271709Smlf gtgt_t *gtgtp = (gtgt_t *)ctl_data;
9281709Smlf ata_drv_t *ata_drvp = GTGTP2ATADRVP(gtgtp);
9291709Smlf int rc;
9301709Smlf
9311709Smlf ADBG_TRACE(("ata_disk_reset entered\n"));
9321709Smlf
9331709Smlf /* XXX - Note that this interface is currently not used by dadk */
9341709Smlf
9351709Smlf if (level == RESET_TARGET) {
9361709Smlf rc = ghd_tran_reset_target(&ata_drvp->ad_ctlp->ac_ccc, gtgtp,
9371709Smlf NULL);
9381709Smlf } else if (level == RESET_ALL) {
9391709Smlf rc = ghd_tran_reset_bus(&ata_drvp->ad_ctlp->ac_ccc, gtgtp,
9401709Smlf NULL);
9411709Smlf }
9421709Smlf
9431709Smlf return (rc ? DDI_SUCCESS : DDI_FAILURE);
9441709Smlf }
9451709Smlf
9461709Smlf
9471709Smlf
9481709Smlf /*
9491709Smlf *
9501709Smlf * DADA ioctl entry point
9511709Smlf *
9521709Smlf */
9531709Smlf
9541709Smlf /* ARGSUSED */
9551709Smlf static int
ata_disk_ioctl(opaque_t ctl_data,int cmd,intptr_t arg,int flag)9561709Smlf ata_disk_ioctl(opaque_t ctl_data, int cmd, intptr_t arg, int flag)
9571709Smlf {
9581709Smlf gtgt_t *gtgtp = (gtgt_t *)ctl_data;
9591709Smlf ata_ctl_t *ata_ctlp = GTGTP2ATAP(gtgtp);
9601709Smlf ata_drv_t *ata_drvp = GTGTP2ATADRVP(gtgtp);
9613652Syt160523 int rc, rc2;
9622799Smarx struct tgdk_geom tgdk;
9632799Smarx int wce;
9641709Smlf struct ata_id *aidp = &ata_drvp->ad_id;
9653652Syt160523 dk_updatefw_t updatefw;
9663652Syt160523 #ifdef _MULTI_DATAMODEL
9673652Syt160523 dk_updatefw_32_t updatefw32;
9683652Syt160523 #endif
9693652Syt160523 dk_disk_id_t dk_disk_id;
9703652Syt160523 char buf[80];
9713652Syt160523 int i;
9723652Syt160523
9731709Smlf
9741709Smlf ADBG_TRACE(("ata_disk_ioctl entered, cmd = %d\n", cmd));
9751709Smlf
9761709Smlf switch (cmd) {
9771709Smlf
9781709Smlf case DIOCTL_GETGEOM:
9791709Smlf case DIOCTL_GETPHYGEOM:
9802799Smarx tgdk.g_cyl = ata_drvp->ad_drvrcyl;
9812799Smarx tgdk.g_head = ata_drvp->ad_drvrhd;
9822799Smarx tgdk.g_sec = ata_drvp->ad_drvrsec;
9832799Smarx tgdk.g_acyl = ata_drvp->ad_acyl;
9842799Smarx tgdk.g_secsiz = 512;
9857821SMark.Logan@Sun.COM tgdk.g_cap = (diskaddr_t)tgdk.g_cyl * tgdk.g_head * tgdk.g_sec;
9862799Smarx if (ddi_copyout(&tgdk, (caddr_t)arg, sizeof (tgdk), flag))
9872799Smarx return (EFAULT);
9881709Smlf return (0);
9891709Smlf
9901709Smlf case DCMD_UPDATE_GEOM:
9911709Smlf /* ??? fix this to issue IDENTIFY DEVICE ??? */
9921709Smlf /* might not be necessary since I don't know of any ATA/IDE that */
9931709Smlf /* can change its geometry. On the other hand, ATAPI devices like the */
9941709Smlf /* LS-120 or PD/CD can change their geometry when new media is inserted */
9951709Smlf return (0);
9961709Smlf
9971709Smlf /* copy the model number into the caller's buffer */
9981709Smlf case DIOCTL_GETMODEL:
9991709Smlf rc = ata_copy_dk_ioc_string(arg, aidp->ai_model,
10001709Smlf sizeof (aidp->ai_model), flag);
10011709Smlf return (rc);
10021709Smlf
10033652Syt160523 /* copy the serial number into the caller's buffer */
10041709Smlf case DIOCTL_GETSERIAL:
10051709Smlf rc = ata_copy_dk_ioc_string(arg, aidp->ai_drvser,
10061709Smlf sizeof (aidp->ai_drvser),
10071709Smlf flag);
10081709Smlf return (rc);
10091709Smlf
10101709Smlf case DIOCTL_GETWCE:
10111709Smlf /*
10121709Smlf * WCE is only supported in ATAPI-4 or higher, for
10131709Smlf * lower rev devices, must assume write cache is
10141709Smlf * enabled.
10151709Smlf * NOTE: Since there is currently no Solaris mechanism
10161709Smlf * to change the state of the Write Cache Enable feature,
10171709Smlf * this code just checks the value of the WCE bit
10181709Smlf * obtained at device init time. If a mechanism
10191709Smlf * is added to the driver to change WCE, this code
10201709Smlf * must be updated appropriately.
10211709Smlf */
10222799Smarx wce = (aidp->ai_majorversion == 0xffff) ||
10231709Smlf ((aidp->ai_majorversion & ATAC_MAJVER_4) == 0) ||
10241709Smlf (aidp->ai_features85 & ATAC_FEATURES85_WCE) != 0;
10252799Smarx
10262799Smarx if (ddi_copyout(&wce, (caddr_t)arg, sizeof (wce), flag) != 0)
10272799Smarx return (EFAULT);
10282799Smarx
10291709Smlf return (0);
10301709Smlf
10311709Smlf case DCMD_GET_STATE:
10321709Smlf rc = ata_queue_cmd(ata_disk_state, NULL, ata_ctlp, ata_drvp,
10331709Smlf gtgtp);
10341709Smlf break;
10351709Smlf
10361709Smlf case DCMD_LOCK:
10371709Smlf case DKIOCLOCK:
10381709Smlf rc = ata_queue_cmd(ata_disk_lock, NULL, ata_ctlp, ata_drvp,
10391709Smlf gtgtp);
10401709Smlf break;
10411709Smlf
10421709Smlf case DCMD_UNLOCK:
10431709Smlf case DKIOCUNLOCK:
10441709Smlf rc = ata_queue_cmd(ata_disk_unlock, NULL, ata_ctlp, ata_drvp,
10451709Smlf gtgtp);
10461709Smlf break;
10471709Smlf
10481709Smlf case DCMD_START_MOTOR:
10491709Smlf case CDROMSTART:
10501709Smlf rc = ata_queue_cmd(ata_disk_recalibrate, NULL, ata_ctlp,
10511709Smlf ata_drvp, gtgtp);
10521709Smlf break;
10531709Smlf
10541709Smlf case DCMD_STOP_MOTOR:
10551709Smlf case CDROMSTOP:
10561709Smlf rc = ata_queue_cmd(ata_disk_standby, NULL, ata_ctlp, ata_drvp,
10571709Smlf gtgtp);
10581709Smlf break;
10591709Smlf
10601709Smlf case DKIOCEJECT:
10611709Smlf case CDROMEJECT:
10621709Smlf rc = ata_queue_cmd(ata_disk_eject, NULL, ata_ctlp, ata_drvp,
10631709Smlf gtgtp);
10641709Smlf break;
10651709Smlf
10663652Syt160523 case DKIOC_UPDATEFW:
10673652Syt160523
10683652Syt160523 /*
10693652Syt160523 * Call DOWNLOAD MICROCODE command to update device
10703652Syt160523 * firmware.
10713652Syt160523 *
10723652Syt160523 * return value:
10733652Syt160523 * normal 0 Download microcode success
10743652Syt160523 * error EFAULT Bad address
10753652Syt160523 * ENXIO No such device or address
10763652Syt160523 * EINVAL Invalid argument
10773652Syt160523 * ENOMEM Not enough core
10783652Syt160523 * ENOTSUP Operation not supported
10793652Syt160523 * EIO I/O error
10803652Syt160523 * EPERM Not owner
10813652Syt160523 */
10823652Syt160523
10833652Syt160523 /*
10843652Syt160523 * The following code deals with handling 32-bit request
10853652Syt160523 * in 64-bit kernel.
10863652Syt160523 */
10873652Syt160523 #ifdef _MULTI_DATAMODEL
10883652Syt160523 if (ddi_model_convert_from(flag & FMODELS) ==
10893652Syt160523 DDI_MODEL_ILP32) {
10903652Syt160523 if (ddi_copyin((void *)arg, &updatefw32,
10913652Syt160523 sizeof (dk_updatefw_32_t), flag))
10923652Syt160523 return (EFAULT);
10933652Syt160523
10943652Syt160523 updatefw.dku_ptrbuf =
10953652Syt160523 (caddr_t)(uintptr_t)updatefw32.dku_ptrbuf;
10963652Syt160523 updatefw.dku_size = updatefw32.dku_size;
10973652Syt160523 updatefw.dku_type = updatefw32.dku_type;
10983652Syt160523 } else {
10993652Syt160523 if (ddi_copyin((void *)arg, &updatefw,
11003652Syt160523 sizeof (dk_updatefw_t), flag))
11013652Syt160523 return (EFAULT);
11023652Syt160523 }
11033652Syt160523 #else
11043652Syt160523 if (ddi_copyin((void *)arg, &updatefw,
11053652Syt160523 sizeof (dk_updatefw_t), flag))
11063652Syt160523 return (EFAULT);
11073652Syt160523 #endif
11083652Syt160523 rc = ata_disk_update_fw(gtgtp, ata_ctlp, ata_drvp,
11093652Syt160523 updatefw.dku_ptrbuf, updatefw.dku_size,
11103652Syt160523 updatefw.dku_type, flag);
11113652Syt160523
11123652Syt160523 /*
11133652Syt160523 * According to ATA8-ACS spec, the new microcode should
11143652Syt160523 * become effective immediately after the transfer of the
11153652Syt160523 * last data segment has completed, so here we will call
11163652Syt160523 * IDENTIFY DEVICE command immediately to update
11173652Syt160523 * ata_id content when success.
11183652Syt160523 */
11193652Syt160523 if (rc == 0) {
11203652Syt160523 rc2 = ata_queue_cmd(ata_disk_id_update, NULL,
11213652Syt160523 ata_ctlp, ata_drvp, gtgtp);
11223652Syt160523 if (rc2 != TRUE) {
11233652Syt160523 return (ENXIO);
11243652Syt160523 } else {
11253652Syt160523 /*
11263652Syt160523 * Check whether the content of the IDENTIFY
11273652Syt160523 * DEVICE data is incomplete, if yes, it's
11283652Syt160523 * because the device supports the Power-up
11293652Syt160523 * in Standby feature set, and we will first
11303652Syt160523 * check word 2, and then decide whether need
11313652Syt160523 * to call set feature to spin-up the device,
11323652Syt160523 * and then call IDENTIFY DEVICE command again.
11333652Syt160523 */
11343652Syt160523 aidp = &ata_drvp->ad_id;
11353652Syt160523 if (aidp->ai_config & ATA_ID_INCMPT) {
11363652Syt160523 if (aidp->ai_resv0 == 0x37c8 ||
11373652Syt160523 aidp->ai_resv0 == 0x738c) {
11383652Syt160523 /* Spin-up the device */
11393652Syt160523 (void) ata_queue_cmd(
11403652Syt160523 ata_disk_set_feature_spinup,
11413652Syt160523 NULL,
11423652Syt160523 ata_ctlp,
11433652Syt160523 ata_drvp,
11443652Syt160523 gtgtp);
11453652Syt160523 }
11463652Syt160523
11473652Syt160523 /* Try to update ata_id again */
11483652Syt160523 rc2 = ata_queue_cmd(
11493652Syt160523 ata_disk_id_update,
11503652Syt160523 NULL,
11513652Syt160523 ata_ctlp,
11523652Syt160523 ata_drvp,
11533652Syt160523 gtgtp);
11543652Syt160523 if (rc2 != TRUE) {
11553652Syt160523 return (ENXIO);
11563652Syt160523 } else {
11573652Syt160523 aidp = &ata_drvp->ad_id;
11583652Syt160523 if (aidp->ai_config &
11593652Syt160523 ATA_ID_INCMPT)
11603652Syt160523 return (ENXIO);
11613652Syt160523 }
11623652Syt160523 }
11633652Syt160523
11643652Syt160523 /*
11653652Syt160523 * Dump the drive information.
11663652Syt160523 */
11673652Syt160523 ATAPRT(("?\tUpdate firmware of %s device at "
11683652Syt160523 "targ %d, lun %d lastlun 0x%x\n",
11693652Syt160523 (ATAPIDRV(ata_drvp) ? "ATAPI":"IDE"),
11703652Syt160523 ata_drvp->ad_targ, ata_drvp->ad_lun,
11713652Syt160523 aidp->ai_lastlun));
11723652Syt160523
11733652Syt160523 (void) strncpy(buf, aidp->ai_model,
11743652Syt160523 sizeof (aidp->ai_model));
11753652Syt160523 buf[sizeof (aidp->ai_model)] = '\0';
11763652Syt160523 for (i = sizeof (aidp->ai_model) - 1;
11773652Syt160523 buf[i] == ' '; i--)
11783652Syt160523 buf[i] = '\0';
11793652Syt160523 ATAPRT(("?\tmodel %s\n", buf));
11803652Syt160523
11813652Syt160523 (void) strncpy(buf, aidp->ai_fw,
11823652Syt160523 sizeof (aidp->ai_fw));
11833652Syt160523 buf[sizeof (aidp->ai_fw)] = '\0';
11843652Syt160523 for (i = sizeof (aidp->ai_fw) - 1;
11853652Syt160523 buf[i] == ' '; i--)
11863652Syt160523 buf[i] = '\0';
11873652Syt160523 ATAPRT(("?\tfw %s\n", buf));
11883652Syt160523 }
11893652Syt160523 }
11903652Syt160523 return (rc);
11913652Syt160523
11923652Syt160523 case DKIOC_GETDISKID:
11933652Syt160523 bzero(&dk_disk_id, sizeof (dk_disk_id_t));
11943652Syt160523
11953652Syt160523 dk_disk_id.dkd_dtype = DKD_ATA_TYPE;
11963652Syt160523
11973652Syt160523 /* Get the model number */
11983652Syt160523 (void) strncpy(dk_disk_id.disk_id.ata_disk_id.dkd_amodel,
11993652Syt160523 aidp->ai_model, sizeof (aidp->ai_model));
12003652Syt160523
12013652Syt160523 /* Get the firmware revision */
12023652Syt160523 (void) strncpy(dk_disk_id.disk_id.ata_disk_id.dkd_afwver,
12033652Syt160523 aidp->ai_fw, sizeof (aidp->ai_fw));
12043652Syt160523
12053652Syt160523 /* Get the serial number */
12063652Syt160523 (void) strncpy(dk_disk_id.disk_id.ata_disk_id.dkd_aserial,
12073652Syt160523 aidp->ai_drvser, sizeof (aidp->ai_drvser));
12083652Syt160523
12093652Syt160523 if (ddi_copyout(&dk_disk_id, (void *)arg,
12103652Syt160523 sizeof (dk_disk_id_t), flag))
12113652Syt160523 return (EFAULT);
12123652Syt160523 else
12133652Syt160523 return (0);
12143652Syt160523
12151709Smlf default:
12161709Smlf ADBG_WARN(("ata_disk_ioctl: unsupported cmd 0x%x\n", cmd));
12171709Smlf return (ENOTTY);
12181709Smlf }
12191709Smlf
12201709Smlf if (rc)
12211709Smlf return (0);
12221709Smlf return (ENXIO);
12231709Smlf
12241709Smlf }
12251709Smlf
12261709Smlf
12271709Smlf #ifdef ___not___used___
12281709Smlf /*
12291709Smlf * Issue an ATA command to the drive using the packet already
12301709Smlf * allocated by the target driver
12311709Smlf */
12321709Smlf
12331709Smlf int
ata_disk_do_ioctl(int (* func)(ata_ctl_t *,ata_drv_t *,ata_pkt_t *),void * arg,ata_ctl_t * ata_ctlp,gtgt_t * gtgtp,cmpkt_t * pktp)12341709Smlf ata_disk_do_ioctl(
12351709Smlf int (*func)(ata_ctl_t *, ata_drv_t *, ata_pkt_t *),
12361709Smlf void *arg,
12371709Smlf ata_ctl_t *ata_ctlp,
12381709Smlf gtgt_t *gtgtp,
12391709Smlf cmpkt_t *pktp)
12401709Smlf {
12411709Smlf gcmd_t *gcmdp = CPKT2GCMD(pktp);
12421709Smlf ata_pkt_t *ata_pktp = GCMD2APKT(gcmdp);
12431709Smlf int rc;
12441709Smlf
12451709Smlf ata_pktp->ap_start = func;
12461709Smlf ata_pktp->ap_intr = NULL;
12471709Smlf ata_pktp->ap_complete = NULL;
12481709Smlf ata_pktp->ap_v_addr = (caddr_t)arg;
12491709Smlf
12501709Smlf /*
12511709Smlf * add it to the queue, when it gets to the front the
12521709Smlf * ap_start function is called.
12531709Smlf */
12541709Smlf rc = ghd_transport(&ata_ctlp->ac_ccc, gcmdp, gcmdp->cmd_gtgtp,
12551709Smlf 0, TRUE, NULL);
12561709Smlf
12571709Smlf if (rc != TRAN_ACCEPT) {
12581709Smlf /* this should never, ever happen */
12591709Smlf return (ENXIO);
12601709Smlf }
12611709Smlf
12621709Smlf if (ata_pktp->ap_flags & AP_ERROR)
12631709Smlf return (ENXIO);
12641709Smlf return (0);
12651709Smlf }
12661709Smlf #endif
12671709Smlf
12681709Smlf
12691709Smlf
12701709Smlf /*
12711709Smlf *
12721709Smlf * DADA pktalloc entry point
12731709Smlf *
12741709Smlf */
12751709Smlf
12761709Smlf /* ARGSUSED */
12771709Smlf static cmpkt_t *
ata_disk_pktalloc(opaque_t ctl_data,int (* callback)(caddr_t),caddr_t arg)12781709Smlf ata_disk_pktalloc(opaque_t ctl_data, int (*callback)(caddr_t), caddr_t arg)
12791709Smlf {
12801709Smlf gtgt_t *gtgtp = (gtgt_t *)ctl_data;
12811709Smlf ata_drv_t *ata_drvp = GTGTP2ATADRVP(gtgtp);
12821709Smlf cmpkt_t *pktp;
12831709Smlf ata_pkt_t *ata_pktp;
12841709Smlf gcmd_t *gcmdp;
12851709Smlf
12861709Smlf ADBG_TRACE(("ata_disk_pktalloc entered\n"));
12871709Smlf
12881709Smlf /*
12891709Smlf * Allocate and init the GHD gcmd_t structure and the
12901709Smlf * DADA cmpkt and the ata_pkt
12911709Smlf */
12921709Smlf if ((gcmdp = ghd_gcmd_alloc(gtgtp,
12931709Smlf (sizeof (cmpkt_t) + sizeof (ata_pkt_t)),
12941709Smlf (callback == DDI_DMA_SLEEP))) == NULL) {
12951709Smlf return ((cmpkt_t *)NULL);
12961709Smlf }
12971709Smlf ASSERT(gcmdp != NULL);
12981709Smlf
12991709Smlf ata_pktp = GCMD2APKT(gcmdp);
13001709Smlf ASSERT(ata_pktp != NULL);
13011709Smlf
13021709Smlf pktp = (cmpkt_t *)(ata_pktp + 1);
13031709Smlf
13041709Smlf pktp->cp_ctl_private = (void *)gcmdp;
13051709Smlf ata_pktp->ap_gcmdp = gcmdp;
13061709Smlf gcmdp->cmd_pktp = (void *)pktp;
13071709Smlf
13081709Smlf /*
13091709Smlf * At this point the structures are linked like this:
13101709Smlf *
13111709Smlf * (struct cmpkt) <--> (struct gcmd) <--> (struct ata_pkt)
13121709Smlf */
13131709Smlf
13141709Smlf /* callback functions */
13151709Smlf
13161709Smlf ata_pktp->ap_start = ata_disk_start;
13171709Smlf ata_pktp->ap_intr = ata_disk_intr;
13181709Smlf ata_pktp->ap_complete = ata_disk_complete;
13191709Smlf
13201709Smlf /* other ata_pkt setup */
13211709Smlf
13221709Smlf ata_pktp->ap_bytes_per_block = ata_drvp->ad_bytes_per_block;
13231709Smlf
13241709Smlf /* cmpkt setup */
13251709Smlf
13261709Smlf pktp->cp_cdblen = 1;
13271709Smlf pktp->cp_cdbp = (opaque_t)&ata_pktp->ap_cdb;
13281709Smlf pktp->cp_scbp = (opaque_t)&ata_pktp->ap_scb;
13291709Smlf pktp->cp_scblen = 1;
13301709Smlf
13311709Smlf return (pktp);
13321709Smlf }
13331709Smlf
13341709Smlf
13351709Smlf
13361709Smlf /*
13371709Smlf *
13381709Smlf * DADA pktfree entry point
13391709Smlf *
13401709Smlf */
13411709Smlf
13421709Smlf /* ARGSUSED */
13431709Smlf static void
ata_disk_pktfree(opaque_t ctl_data,cmpkt_t * pktp)13441709Smlf ata_disk_pktfree(opaque_t ctl_data, cmpkt_t *pktp)
13451709Smlf {
13461709Smlf ata_pkt_t *ata_pktp = CPKT2APKT(pktp);
13471709Smlf
13481709Smlf ADBG_TRACE(("ata_disk_pktfree entered\n"));
13491709Smlf
13501709Smlf /* check not free already */
13511709Smlf
13521709Smlf ASSERT(!(ata_pktp->ap_flags & AP_FREE));
13531709Smlf ata_pktp->ap_flags = AP_FREE;
13541709Smlf
13551709Smlf ghd_gcmd_free(CPKT2GCMD(pktp));
13561709Smlf }
13571709Smlf
13581709Smlf
13591709Smlf /*
13601709Smlf *
13611709Smlf * DADA memsetup entry point
13621709Smlf *
13631709Smlf */
13641709Smlf
13651709Smlf /* ARGSUSED */
13661709Smlf static cmpkt_t *
ata_disk_memsetup(opaque_t ctl_data,cmpkt_t * pktp,struct buf * bp,int (* callback)(caddr_t),caddr_t arg)13671709Smlf ata_disk_memsetup(
13681709Smlf opaque_t ctl_data,
13691709Smlf cmpkt_t *pktp,
13701709Smlf struct buf *bp,
13711709Smlf int (*callback)(caddr_t),
13721709Smlf caddr_t arg)
13731709Smlf {
13741709Smlf gtgt_t *gtgtp = (gtgt_t *)ctl_data;
13751709Smlf ata_pkt_t *ata_pktp = CPKT2APKT(pktp);
13761709Smlf gcmd_t *gcmdp = APKT2GCMD(ata_pktp);
13771709Smlf int flags;
13781709Smlf
13791709Smlf ADBG_TRACE(("ata_disk_memsetup entered\n"));
13801709Smlf
13811709Smlf ata_pktp->ap_sg_cnt = 0;
13821709Smlf
13831709Smlf if (bp->b_bcount == 0) {
13841709Smlf ata_pktp->ap_v_addr = NULL;
13851709Smlf return (pktp);
13861709Smlf }
13871709Smlf
13881709Smlf if (GTGTP2ATADRVP(gtgtp)->ad_pciide_dma != ATA_DMA_ON)
13891709Smlf goto skip_dma_setup;
13901709Smlf
13911709Smlf if (ata_dma_disabled)
13921709Smlf goto skip_dma_setup;
13931709Smlf
13941709Smlf /*
13951709Smlf * The PCI-IDE DMA engine is brain-damaged and can't
13961709Smlf * DMA non-aligned buffers.
13971709Smlf */
13981709Smlf if (!(bp->b_flags & B_PAGEIO) &&
13991709Smlf ((uintptr_t)bp->b_un.b_addr) & PCIIDE_PRDE_ADDR_MASK) {
14001709Smlf goto skip_dma_setup;
14011709Smlf }
14021709Smlf
14031709Smlf /*
14041709Smlf * It also insists that the byte count must be even.
14051709Smlf */
14061709Smlf if (bp->b_bcount & 1)
14071709Smlf goto skip_dma_setup;
14081709Smlf
14091709Smlf /* check direction for data transfer */
14101709Smlf if (bp->b_flags & B_READ) {
14111709Smlf flags = DDI_DMA_READ | DDI_DMA_PARTIAL;
14121709Smlf } else {
14131709Smlf flags = DDI_DMA_WRITE | DDI_DMA_PARTIAL;
14141709Smlf }
14151709Smlf
14161709Smlf /*
14171709Smlf * Bind the DMA handle to the buf
14181709Smlf */
14191709Smlf if (ghd_dma_buf_bind_attr(>GTP2ATAP(gtgtp)->ac_ccc, gcmdp, bp, flags,
14201709Smlf callback, arg, >GTP2ATATGTP(gtgtp)->at_dma_attr)) {
14211709Smlf ata_pktp->ap_v_addr = 0;
14221709Smlf return (pktp);
14231709Smlf }
14241709Smlf
14251709Smlf skip_dma_setup:
14261709Smlf bp_mapin(bp);
14271709Smlf ata_pktp->ap_v_addr = bp->b_un.b_addr;
14281709Smlf return (pktp);
14291709Smlf }
14301709Smlf
14311709Smlf
14321709Smlf
14331709Smlf /*
14341709Smlf *
14351709Smlf * DADA memfree entry point
14361709Smlf *
14371709Smlf */
14381709Smlf
14391709Smlf /*
14401709Smlf * 1157317 sez that drivers shouldn't call bp_mapout(), as either
14411709Smlf * biodone() or biowait() will end up doing it, but after they
14421709Smlf * call bp->b_iodone(), which is a necessary sequence for
14431709Smlf * Online Disk Suite. However, the DDI group wants to rethink
14441709Smlf * bp_mapin()/bp_mapout() and how they should behave in the
14451709Smlf * presence of layered drivers, etc. For the moment, fix
14461709Smlf * the OLDS problem by removing the bp_mapout() call.
14471709Smlf */
14481709Smlf
14491709Smlf #define BUG_1157317
14501709Smlf
14511709Smlf /* ARGSUSED */
14521709Smlf static void
ata_disk_memfree(opaque_t ctl_data,cmpkt_t * pktp)14531709Smlf ata_disk_memfree(opaque_t ctl_data, cmpkt_t *pktp)
14541709Smlf {
14551709Smlf gcmd_t *gcmdp = CPKT2GCMD(pktp);
14561709Smlf
14571709Smlf ADBG_TRACE(("ata_disk_memfree entered\n"));
14581709Smlf
14591709Smlf if (gcmdp->cmd_dma_handle)
14601709Smlf ghd_dmafree_attr(gcmdp);
14611709Smlf #if !defined(BUG_1157317)
14621709Smlf else
14631709Smlf bp_mapout(pktp->cp_bp);
14641709Smlf #endif
14651709Smlf }
14661709Smlf
14671709Smlf
14681709Smlf
14691709Smlf /*
14701709Smlf *
14711709Smlf * DADA iosetup entry point
14721709Smlf *
14731709Smlf */
14741709Smlf
14751709Smlf static cmpkt_t *
ata_disk_iosetup(opaque_t ctl_data,cmpkt_t * pktp)14761709Smlf ata_disk_iosetup(opaque_t ctl_data, cmpkt_t *pktp)
14771709Smlf {
14781709Smlf gtgt_t *gtgtp = (gtgt_t *)ctl_data;
14791709Smlf ata_drv_t *ata_drvp = GTGTP2ATADRVP(gtgtp);
14801709Smlf ata_pkt_t *ata_pktp = CPKT2APKT(pktp);
14811709Smlf gcmd_t *gcmdp = APKT2GCMD(ata_pktp);
14821709Smlf uint_t sec_count;
14831709Smlf daddr_t start_sec;
14841709Smlf uint_t byte_count;
14851709Smlf
14861709Smlf ADBG_TRACE(("ata_disk_iosetup entered\n"));
14871709Smlf
14881709Smlf /*
14891709Smlf * Check for DCMD_FLUSH_CACHE (which does no I/O) and
14901709Smlf * just do basic setup.
14911709Smlf */
14921709Smlf if (pktp->cp_passthru == NULL &&
14931709Smlf ata_pktp->ap_cdb == DCMD_FLUSH_CACHE) {
14941709Smlf ata_pktp->ap_cmd = ATC_FLUSH_CACHE;
14951709Smlf ata_pktp->ap_flags = 0;
14961709Smlf ata_pktp->ap_count = 0;
14971709Smlf ata_pktp->ap_startsec = 0;
14981709Smlf ata_pktp->ap_sg_cnt = 0;
14991709Smlf ata_pktp->ap_pciide_dma = FALSE;
15001709Smlf return (pktp);
15011709Smlf }
15021709Smlf
15031709Smlf /* check for error retry */
15041709Smlf if (ata_pktp->ap_flags & AP_ERROR) {
15051709Smlf /*
15061709Smlf * this is a temporary work-around for dadk calling
15071709Smlf * iosetup for retry. The correct
15081709Smlf * solution is changing dadk to not to call iosetup
15091709Smlf * for a retry.
15101709Smlf * We do not apply the work-around for pio mode since
15111709Smlf * that does not involve moving dma windows and reducing the
15121709Smlf * sector count would work for pio mode on a retry
15131709Smlf * for now.
15141709Smlf */
15151709Smlf if (gcmdp->cmd_dma_handle != NULL) {
15161709Smlf ata_pktp->ap_flags = 0;
15171709Smlf return (NULL);
15181709Smlf }
15191709Smlf
15201709Smlf ata_pktp->ap_bytes_per_block = NBPSCTR;
15211709Smlf sec_count = 1;
15221709Smlf
15231709Smlf /*
15241709Smlf * Since we are retrying the last read or write operation,
15251709Smlf * restore the old values of the ap_v_addr and ap_resid.
15261709Smlf * This assumes CTL_IOSETUP is called again on retry; if not,
15271709Smlf * this needs to be done in CTL_TRANSPORT.
15281709Smlf */
15291709Smlf if (ata_pktp->ap_flags & (AP_READ | AP_WRITE)) {
15301709Smlf ata_pktp->ap_v_addr = ata_pktp->ap_v_addr_sav;
15311709Smlf ata_pktp->ap_resid = ata_pktp->ap_resid_sav;
15321709Smlf }
15331709Smlf } else {
15341709Smlf /*
15351709Smlf * Limit request to ac_max_transfer sectors.
15361709Smlf * The value is specified by the user in the
15371709Smlf * max_transfer property. It must be in the range 1 to 256.
15381709Smlf * When max_transfer is 0x100 it is bigger than 8 bits.
15391709Smlf * The spec says 0 represents 256 so it should be OK.
15401709Smlf */
15411709Smlf sec_count = min((pktp->cp_bytexfer >> SCTRSHFT),
15421709Smlf ata_drvp->ad_ctlp->ac_max_transfer);
15431709Smlf /*
15441709Smlf * Save the current values of ap_v_addr and ap_resid
15451709Smlf * in case a retry operation happens. During a retry
15461709Smlf * operation we need to restore these values.
15471709Smlf */
15481709Smlf ata_pktp->ap_v_addr_sav = ata_pktp->ap_v_addr;
15491709Smlf ata_pktp->ap_resid_sav = ata_pktp->ap_resid;
15501709Smlf }
15511709Smlf
15521709Smlf /* reset flags */
15531709Smlf ata_pktp->ap_flags = 0;
15541709Smlf
15551709Smlf #ifdef DADKIO_RWCMD_READ
15561709Smlf start_sec = pktp->cp_passthru ? RWCMDP(pktp)->blkaddr : pktp->cp_srtsec;
15571709Smlf #else
15581709Smlf start_sec = pktp->cp_srtsec;
15591709Smlf #endif
15601709Smlf
15611709Smlf /*
15621709Smlf * Setup the PCIDE Bus Master Scatter/Gather list
15631709Smlf */
15641709Smlf ata_pktp->ap_sg_cnt = 0;
15651709Smlf ata_pktp->ap_pciide_dma = FALSE;
15661709Smlf if (gcmdp->cmd_dma_handle != NULL && sec_count != 0) {
15671709Smlf byte_count = sec_count << SCTRSHFT;
15681709Smlf if ((ghd_dmaget_attr(>GTP2ATAP(gtgtp)->ac_ccc, gcmdp,
15691709Smlf byte_count, ATA_DMA_NSEGS, &byte_count) == FALSE) ||
15701709Smlf (byte_count == 0)) {
15711709Smlf ADBG_ERROR(("ata_disk_iosetup: byte count zero\n"));
15721709Smlf return (NULL);
15731709Smlf }
15741709Smlf sec_count = byte_count >> SCTRSHFT;
15751709Smlf }
15761709Smlf
15771709Smlf /*
15781709Smlf * In the non-48-bit mode addressing (CHS and LBA28) the sector
15791709Smlf * count is a 8-bit value and the sector count 0 represents 256
15801709Smlf * sectors.
15811709Smlf * In the extended addressing (LBA48) the sector count is a 16-bit
15821709Smlf * value, so max_transfer 0x100 cannot be truncated to 8-bits
15831709Smlf * because this would represent a zero sector count.
15841709Smlf */
15857671SZhongyan.Gu@Sun.COM ata_pktp->ap_count = (ushort_t)sec_count;
15861709Smlf if (!(ata_drvp->ad_flags & AD_EXT48)) {
15871709Smlf ata_pktp->ap_count &= 0xff;
15881709Smlf }
15891709Smlf ata_pktp->ap_startsec = start_sec;
15901709Smlf
15911709Smlf #ifdef DADKIO_RWCMD_READ
15921709Smlf if (pktp->cp_passthru) {
15931709Smlf switch (RWCMDP(pktp)->cmd) {
15941709Smlf case DADKIO_RWCMD_READ:
15951709Smlf if (ata_pktp->ap_sg_cnt) {
15961709Smlf ata_pktp->ap_cmd = ATC_READ_DMA;
15971709Smlf ata_pktp->ap_pciide_dma = TRUE;
15981709Smlf ata_pktp->ap_start = ata_disk_start_dma_in;
15991709Smlf ata_pktp->ap_intr = ata_disk_intr_dma;
16001709Smlf } else {
16011709Smlf ata_pktp->ap_cmd = ATC_RDSEC;
16021709Smlf ata_pktp->ap_start = ata_disk_start_pio_in;
16031709Smlf ata_pktp->ap_intr = ata_disk_intr_pio_in;
16041709Smlf }
16051709Smlf ata_pktp->ap_flags |= AP_READ;
16061709Smlf break;
16071709Smlf case DADKIO_RWCMD_WRITE:
16081709Smlf if (ata_pktp->ap_sg_cnt) {
16091709Smlf ata_pktp->ap_cmd = ATC_WRITE_DMA;
16101709Smlf ata_pktp->ap_pciide_dma = TRUE;
16111709Smlf ata_pktp->ap_start = ata_disk_start_dma_out;
16121709Smlf ata_pktp->ap_intr = ata_disk_intr_dma;
16131709Smlf } else {
16141709Smlf ata_pktp->ap_cmd = ATC_WRSEC;
16151709Smlf ata_pktp->ap_start = ata_disk_start_pio_out;
16161709Smlf ata_pktp->ap_intr = ata_disk_intr_pio_out;
16171709Smlf }
16181709Smlf ata_pktp->ap_flags |= AP_WRITE;
16191709Smlf break;
16201709Smlf }
16211709Smlf
16221709Smlf byte_count = RWCMDP(pktp)->buflen;
16231709Smlf pktp->cp_bytexfer = byte_count;
16241709Smlf pktp->cp_resid = byte_count;
16251709Smlf ata_pktp->ap_resid = byte_count;
16261709Smlf
16271709Smlf /*
16281709Smlf * since we're not using READ/WRITE MULTIPLE, we
16291709Smlf * should set bytes_per_block to one sector
16301709Smlf * XXX- why wasn't this in the old driver??
16311709Smlf */
16321709Smlf ata_pktp->ap_bytes_per_block = NBPSCTR;
16331709Smlf } else
16341709Smlf #endif
16351709Smlf {
16361709Smlf byte_count = sec_count << SCTRSHFT;
16371709Smlf pktp->cp_bytexfer = byte_count;
16381709Smlf pktp->cp_resid = byte_count;
16391709Smlf ata_pktp->ap_resid = byte_count;
16401709Smlf
16411709Smlf /* setup the task file registers */
16421709Smlf
16431709Smlf switch (ata_pktp->ap_cdb) {
16441709Smlf case DCMD_READ:
16451709Smlf if (ata_pktp->ap_sg_cnt) {
16461709Smlf ata_pktp->ap_cmd = ATC_READ_DMA;
16471709Smlf ata_pktp->ap_pciide_dma = TRUE;
16481709Smlf ata_pktp->ap_start = ata_disk_start_dma_in;
16491709Smlf ata_pktp->ap_intr = ata_disk_intr_dma;
16501709Smlf } else {
16511709Smlf ata_pktp->ap_cmd = ata_drvp->ad_rd_cmd;
16521709Smlf ata_pktp->ap_start = ata_disk_start_pio_in;
16531709Smlf ata_pktp->ap_intr = ata_disk_intr_pio_in;
16541709Smlf }
16551709Smlf ata_pktp->ap_flags |= AP_READ;
16561709Smlf break;
16571709Smlf
16581709Smlf case DCMD_WRITE:
16591709Smlf if (ata_pktp->ap_sg_cnt) {
16601709Smlf ata_pktp->ap_cmd = ATC_WRITE_DMA;
16611709Smlf ata_pktp->ap_pciide_dma = TRUE;
16621709Smlf ata_pktp->ap_start = ata_disk_start_dma_out;
16631709Smlf ata_pktp->ap_intr = ata_disk_intr_dma;
16641709Smlf } else {
16651709Smlf ata_pktp->ap_cmd = ata_drvp->ad_wr_cmd;
16661709Smlf ata_pktp->ap_start = ata_disk_start_pio_out;
16671709Smlf ata_pktp->ap_intr = ata_disk_intr_pio_out;
16681709Smlf }
16691709Smlf ata_pktp->ap_flags |= AP_WRITE;
16701709Smlf break;
16711709Smlf
16721709Smlf default:
16731709Smlf ADBG_WARN(("ata_disk_iosetup: unknown command 0x%x\n",
16741709Smlf ata_pktp->ap_cdb));
16751709Smlf pktp = NULL;
16761709Smlf break;
16771709Smlf }
16781709Smlf }
16791709Smlf
16801709Smlf /* If 48-bit mode is used, convert command to 48-bit mode cmd */
16811709Smlf if (pktp != NULL && ata_drvp->ad_flags & AD_EXT48) {
16821709Smlf switch (ata_pktp->ap_cmd) {
16831709Smlf case ATC_RDSEC:
16841709Smlf ata_pktp->ap_cmd = ATC_RDSEC_EXT;
16851709Smlf break;
16861709Smlf case ATC_WRSEC:
16871709Smlf ata_pktp->ap_cmd = ATC_WRSEC_EXT;
16881709Smlf break;
16891709Smlf case ATC_RDMULT:
16901709Smlf ata_pktp->ap_cmd = ATC_RDMULT_EXT;
16911709Smlf break;
16921709Smlf case ATC_WRMULT:
16931709Smlf ata_pktp->ap_cmd = ATC_WRMULT_EXT;
16941709Smlf break;
16951709Smlf case ATC_READ_DMA:
16961709Smlf ata_pktp->ap_cmd = ATC_RDDMA_EXT;
16971709Smlf break;
16981709Smlf case ATC_WRITE_DMA:
16991709Smlf ata_pktp->ap_cmd = ATC_WRDMA_EXT;
17001709Smlf break;
17011709Smlf }
17021709Smlf }
17031709Smlf
17041709Smlf return (pktp);
17051709Smlf }
17061709Smlf
17071709Smlf
17081709Smlf
17091709Smlf /*
17101709Smlf *
17111709Smlf * DADA transport entry point
17121709Smlf *
17131709Smlf */
17141709Smlf
17151709Smlf static int
ata_disk_transport(opaque_t ctl_data,cmpkt_t * pktp)17161709Smlf ata_disk_transport(opaque_t ctl_data, cmpkt_t *pktp)
17171709Smlf {
17181709Smlf gtgt_t *gtgtp = (gtgt_t *)ctl_data;
17191709Smlf ata_drv_t *ata_drvp = GTGTP2ATADRVP(gtgtp);
17201709Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
17211709Smlf ata_pkt_t *ata_pktp = CPKT2APKT(pktp);
17221709Smlf int rc;
17231709Smlf int polled = FALSE;
17241709Smlf
17251709Smlf ADBG_TRACE(("ata_disk_transport entered\n"));
17261709Smlf
17271709Smlf /* check for polling pkt */
17281709Smlf
17291709Smlf if (pktp->cp_flags & CPF_NOINTR) {
17301709Smlf polled = TRUE;
17311709Smlf }
17321709Smlf
17331709Smlf /* call ghd transport routine */
17341709Smlf
17351709Smlf rc = ghd_transport(&ata_ctlp->ac_ccc, APKT2GCMD(ata_pktp),
17361709Smlf gtgtp, pktp->cp_time, polled, NULL);
17371709Smlf
17381709Smlf /* see if pkt was not accepted */
17391709Smlf
17401709Smlf if (rc == TRAN_BUSY)
17411709Smlf return (CTL_SEND_BUSY);
17421709Smlf
17431709Smlf if (rc == TRAN_ACCEPT)
17441709Smlf return (CTL_SEND_SUCCESS);
17451709Smlf
17461709Smlf return (CTL_SEND_FAILURE);
17471709Smlf }
17481709Smlf
17491709Smlf
17501709Smlf /*
17511709Smlf *
17521709Smlf * routines to load the cylinder/head/sector/count
17531709Smlf * task file registers.
17541709Smlf *
17551709Smlf */
17561709Smlf static void
ata_disk_load_regs_lba28(ata_pkt_t * ata_pktp,ata_drv_t * ata_drvp)17571709Smlf ata_disk_load_regs_lba28(ata_pkt_t *ata_pktp, ata_drv_t *ata_drvp)
17581709Smlf {
17591709Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
17601709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
17611709Smlf uint_t lba; /* LBA of first sector */
17621709Smlf
17631709Smlf lba = ata_pktp->ap_startsec;
17641709Smlf
17651709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count,
17661709Smlf ata_pktp->ap_count);
17671709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect, lba);
17681709Smlf lba >>= 8;
17691709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_lcyl, lba);
17701709Smlf lba >>= 8;
17711709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_hcyl, lba);
17721709Smlf lba >>= 8;
17731709Smlf /*
17741709Smlf * dev/head register can use only 4 bits
17751709Smlf * must also include drive selector.
17761709Smlf */
17771709Smlf lba = (lba & 0xf) | ata_drvp->ad_drive_bits;
17781709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, lba);
17791709Smlf }
17801709Smlf
17811709Smlf /*
17821709Smlf * In 48-bit extended mode, the sector count is 16 bits wide, and the
17831709Smlf * LBA is 48 bits wide, as follows:
17841709Smlf * register most recent previous
17851709Smlf * name value value
17861709Smlf * -------- ---------- ---------
17871709Smlf * sector cnt count(7:0) count(15:8)
17881709Smlf * sector num lba(7:0) lba(31:24)
17891709Smlf * cyl low lba(15:8) lba(39:32)
17901709Smlf * cyl hi lba(23:16) lba(47:40)
17911709Smlf * device/head 111D0000 N/A
17921709Smlf * ^ ^
17931709Smlf * | |
17941709Smlf * | +-- drive number
17951709Smlf * |
17961709Smlf * +-- indicates LBA
17971709Smlf * The other two 1 bits are historical and are not used in 48bit
17981709Smlf * extended mode.
17991709Smlf */
18001709Smlf /*
18011709Smlf * WARNING:
18021709Smlf * dada framework passes starting sector as daddr_t type, thus
18031709Smlf * limiting reachable disk space in 32-bit x86 architecture to 1 terabyte.
18041709Smlf * Therefore high 16 bits of the 48-bits address can be and
18051709Smlf * are currently ignored.
18061709Smlf */
18071709Smlf static void
ata_disk_load_regs_lba48(ata_pkt_t * ata_pktp,ata_drv_t * ata_drvp)18081709Smlf ata_disk_load_regs_lba48(ata_pkt_t *ata_pktp, ata_drv_t *ata_drvp)
18091709Smlf {
18101709Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
18111709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
18121709Smlf uint16_t seccnt; /* 16-bit sector count */
18131709Smlf uint_t lbalow; /* low-order 24 bits of LBA */
18141709Smlf uint_t lbahi; /* high-order 24 bits of LBA */
18151709Smlf
18161709Smlf seccnt = ata_pktp->ap_count;
18171709Smlf /* high-order 8 bits of lbalow never get used */
18181709Smlf lbalow = ata_pktp->ap_startsec;
18191709Smlf lbahi = ata_pktp->ap_startsec >> 24;
18201709Smlf
18211709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count, seccnt >> 8);
18221709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count, seccnt);
18231709Smlf /* Send the high-order half first */
18241709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect, lbahi);
18251709Smlf lbahi >>= 8;
18261709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_lcyl, lbahi);
18271709Smlf lbahi >>= 8;
18281709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_hcyl, lbahi);
18291709Smlf /* Send the low-order half */
18301709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect, lbalow);
18311709Smlf lbalow >>= 8;
18321709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_lcyl, lbalow);
18331709Smlf lbalow >>= 8;
18341709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_hcyl, lbalow);
18351709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd,
18361709Smlf ata_drvp->ad_drive_bits);
18371709Smlf }
18381709Smlf
18391709Smlf static void
ata_disk_load_regs_chs(ata_pkt_t * ata_pktp,ata_drv_t * ata_drvp)18401709Smlf ata_disk_load_regs_chs(ata_pkt_t *ata_pktp, ata_drv_t *ata_drvp)
18411709Smlf {
18421709Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
18431709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
18441709Smlf uint_t resid;
18451709Smlf uint_t cyl;
18461709Smlf uchar_t head;
18471709Smlf uchar_t drvheads;
18481709Smlf uchar_t drvsectors;
18491709Smlf
18501709Smlf drvheads = ata_drvp->ad_phhd;
18511709Smlf drvsectors = ata_drvp->ad_phsec;
18521709Smlf
18531709Smlf resid = ata_pktp->ap_startsec / drvsectors;
18541709Smlf head = (resid % drvheads) & 0xf;
18551709Smlf cyl = resid / drvheads;
18561709Smlf /* automatically truncate to char */
18571709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_sect,
18581709Smlf (ata_pktp->ap_startsec % drvsectors) + 1);
18591709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_count, ata_pktp->ap_count);
18601709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_hcyl, (cyl >> 8));
18611709Smlf /* lcyl gets truncated to 8 bits */
18621709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_lcyl, cyl);
18631709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd,
18641709Smlf ata_drvp->ad_drive_bits | head);
18651709Smlf }
18661709Smlf
18671709Smlf
18681709Smlf /*
18691709Smlf *
18701709Smlf * packet start callback routines
18711709Smlf *
18721709Smlf */
18731709Smlf
18741709Smlf /* ARGSUSED */
18751709Smlf static int
ata_disk_start_common(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)18761709Smlf ata_disk_start_common(
18771709Smlf ata_ctl_t *ata_ctlp,
18781709Smlf ata_drv_t *ata_drvp,
18791709Smlf ata_pkt_t *ata_pktp)
18801709Smlf {
18811709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
18821709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
18831709Smlf
18841709Smlf ADBG_TRACE(("ata_disk_start_common entered\n"));
18851709Smlf
18861709Smlf ADBG_TRANSPORT(("ata_disk_start:\tpkt = 0x%p, pkt flags = 0x%x\n",
18871709Smlf ata_pktp, ata_pktp->ap_flags));
18881709Smlf ADBG_TRANSPORT(("\tcommand=0x%x, sect=0x%lx\n",
18891709Smlf ata_pktp->ap_cmd, ata_pktp->ap_startsec));
18901709Smlf ADBG_TRANSPORT(("\tcount=0x%x, drvhd = 0x%x\n",
18911709Smlf ata_pktp->ap_count, ata_drvp->ad_drive_bits));
18921709Smlf
18931709Smlf /*
18941709Smlf * If AC_BSY_WAIT is set, wait for controller to not be busy,
18951709Smlf * before issuing a command. If AC_BSY_WAIT is not set,
18961709Smlf * skip the wait. This is important for laptops that do
18971709Smlf * suspend/resume but do not correctly wait for the busy bit to
18981709Smlf * drop after a resume.
18991709Smlf *
19001709Smlf * NOTE: this test for ATS_BSY is also needed if/when we
19011709Smlf * implement the overlapped/queued command protocols. Currently,
19021709Smlf * the overlap/queued feature is not supported so the test is
19031709Smlf * conditional.
19041709Smlf */
19051709Smlf if (ata_ctlp->ac_timing_flags & AC_BSY_WAIT) {
19061709Smlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2,
19071709Smlf 0, ATS_BSY, 5000000)) {
19081709Smlf ADBG_ERROR(("ata_disk_start: BUSY\n"));
19091709Smlf return (FALSE);
19101709Smlf }
19111709Smlf }
19121709Smlf
19131709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_drvp->ad_drive_bits);
19144852Smlf ata_nsecwait(400);
19151709Smlf
19161709Smlf /*
19171709Smlf * make certain the drive selected
19181709Smlf */
19191709Smlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2,
19201709Smlf ATS_DRDY, ATS_BSY, 5 * 1000000)) {
19211709Smlf ADBG_ERROR(("ata_disk_start: select failed\n"));
19221709Smlf return (FALSE);
19231709Smlf }
19241709Smlf
19253652Syt160523 if (ata_pktp->ap_cmd == ATC_LOAD_FW) {
19263652Syt160523
19273652Syt160523 /* the sector count is 16 bits wide */
19283652Syt160523 ddi_put8(io_hdl1, ata_ctlp->ac_count, ata_pktp->ap_count);
19293652Syt160523 ddi_put8(io_hdl1, ata_ctlp->ac_sect, ata_pktp->ap_count >> 8);
19303652Syt160523 ddi_put8(io_hdl1, ata_ctlp->ac_lcyl, ata_pktp->ap_startsec);
19313652Syt160523 ddi_put8(io_hdl1, ata_ctlp->ac_hcyl,
19323652Syt160523 ata_pktp->ap_startsec >> 8);
19333652Syt160523
19343652Syt160523 /* put subcommand for DOWNLOAD MICROCODE */
19353652Syt160523 ddi_put8(io_hdl1, ata_ctlp->ac_feature, ata_pktp->ap_bcount);
19363652Syt160523 } else {
19373652Syt160523
19383652Syt160523 /*
19393652Syt160523 * We use different methods for loading the task file
19403652Syt160523 * registers, depending on whether the disk
19413652Syt160523 * uses LBA or CHS addressing and whether 48-bit
19423652Syt160523 * extended addressing is to be used.
19433652Syt160523 */
19443652Syt160523 if (!(ata_drvp->ad_drive_bits & ATDH_LBA))
19453652Syt160523 ata_disk_load_regs_chs(ata_pktp, ata_drvp);
19463652Syt160523 else if (ata_drvp->ad_flags & AD_EXT48)
19473652Syt160523 ata_disk_load_regs_lba48(ata_pktp, ata_drvp);
19483652Syt160523 else
19493652Syt160523 ata_disk_load_regs_lba28(ata_pktp, ata_drvp);
19503652Syt160523 ddi_put8(io_hdl1, ata_ctlp->ac_feature, 0);
19513652Syt160523 }
19521709Smlf
19531709Smlf /*
19541709Smlf * Always make certain interrupts are enabled. It's been reported
19551709Smlf * (but not confirmed) that some notebook computers don't
19561709Smlf * clear the interrupt disable bit after being resumed. The
19571709Smlf * easiest way to fix this is to always clear the disable bit
19581709Smlf * before every command.
19591709Smlf */
19601709Smlf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, ATDC_D3);
19611709Smlf return (TRUE);
19621709Smlf }
19631709Smlf
19641709Smlf
19651709Smlf /*
19661709Smlf *
19671709Smlf * Start a non-data ATA command (not DMA and not PIO):
19681709Smlf *
19691709Smlf */
19701709Smlf
19711709Smlf static int
ata_disk_start(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)19721709Smlf ata_disk_start(
19731709Smlf ata_ctl_t *ata_ctlp,
19741709Smlf ata_drv_t *ata_drvp,
19751709Smlf ata_pkt_t *ata_pktp)
19761709Smlf {
19771709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
19781709Smlf int rc;
19791709Smlf
19801709Smlf rc = ata_disk_start_common(ata_ctlp, ata_drvp, ata_pktp);
19811709Smlf
19821709Smlf if (!rc)
19831709Smlf return (ATA_FSM_RC_BUSY);
19841709Smlf
19851709Smlf /*
19861709Smlf * This next one sets the controller in motion
19871709Smlf */
19881709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ata_pktp->ap_cmd);
19891709Smlf
19901709Smlf /* wait for the busy bit to settle */
19914852Smlf ata_nsecwait(400);
19921709Smlf
19931709Smlf return (ATA_FSM_RC_OKAY);
19941709Smlf }
19951709Smlf
19961709Smlf
19971709Smlf
19981709Smlf static int
ata_disk_start_dma_in(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)19991709Smlf ata_disk_start_dma_in(
20001709Smlf ata_ctl_t *ata_ctlp,
20011709Smlf ata_drv_t *ata_drvp,
20021709Smlf ata_pkt_t *ata_pktp)
20031709Smlf {
20041709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
20051709Smlf int rc;
20061709Smlf
20071709Smlf rc = ata_disk_start_common(ata_ctlp, ata_drvp, ata_pktp);
20081709Smlf
20091709Smlf if (!rc)
20101709Smlf return (ATA_FSM_RC_BUSY);
20111709Smlf
20121709Smlf /*
20131709Smlf * Copy the Scatter/Gather list to the controller's
20141709Smlf * Physical Region Descriptor Table
20151709Smlf */
20161709Smlf ata_pciide_dma_setup(ata_ctlp, ata_pktp->ap_sg_list,
20171709Smlf ata_pktp->ap_sg_cnt);
20181709Smlf
20191709Smlf /*
20201709Smlf * reset the PCIIDE Controller's interrupt and error status bits
20211709Smlf */
20221709Smlf (void) ata_pciide_status_clear(ata_ctlp);
20231709Smlf
20241709Smlf /*
20251709Smlf * This next one sets the drive in motion
20261709Smlf */
20271709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ata_pktp->ap_cmd);
20281709Smlf
20291709Smlf /* wait for the drive's busy bit to settle */
20304852Smlf ata_nsecwait(400);
20311709Smlf
20321709Smlf ata_pciide_dma_start(ata_ctlp, PCIIDE_BMICX_RWCON_WRITE_TO_MEMORY);
20331709Smlf
20341709Smlf return (ATA_FSM_RC_OKAY);
20351709Smlf }
20361709Smlf
20371709Smlf
20381709Smlf
20391709Smlf static int
ata_disk_start_dma_out(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)20401709Smlf ata_disk_start_dma_out(
20411709Smlf ata_ctl_t *ata_ctlp,
20421709Smlf ata_drv_t *ata_drvp,
20431709Smlf ata_pkt_t *ata_pktp)
20441709Smlf {
20451709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
20461709Smlf int rc;
20471709Smlf
20481709Smlf rc = ata_disk_start_common(ata_ctlp, ata_drvp, ata_pktp);
20491709Smlf
20501709Smlf if (!rc)
20511709Smlf return (ATA_FSM_RC_BUSY);
20521709Smlf
20531709Smlf /*
20541709Smlf * Copy the Scatter/Gather list to the controller's
20551709Smlf * Physical Region Descriptor Table
20561709Smlf */
20571709Smlf ata_pciide_dma_setup(ata_ctlp, ata_pktp->ap_sg_list,
20581709Smlf ata_pktp->ap_sg_cnt);
20591709Smlf
20601709Smlf /*
20611709Smlf * reset the PCIIDE Controller's interrupt and error status bits
20621709Smlf */
20631709Smlf (void) ata_pciide_status_clear(ata_ctlp);
20641709Smlf
20651709Smlf /*
20661709Smlf * This next one sets the drive in motion
20671709Smlf */
20681709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ata_pktp->ap_cmd);
20691709Smlf
20701709Smlf /* wait for the drive's busy bit to settle */
20714852Smlf ata_nsecwait(400);
20721709Smlf
20731709Smlf ata_pciide_dma_start(ata_ctlp, PCIIDE_BMICX_RWCON_READ_FROM_MEMORY);
20741709Smlf
20751709Smlf return (ATA_FSM_RC_OKAY);
20761709Smlf }
20771709Smlf
20781709Smlf
20791709Smlf
20801709Smlf
20811709Smlf
20821709Smlf /*
20831709Smlf *
20841709Smlf * Start a PIO data-in ATA command:
20851709Smlf *
20861709Smlf */
20871709Smlf
20881709Smlf static int
ata_disk_start_pio_in(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)20891709Smlf ata_disk_start_pio_in(
20901709Smlf ata_ctl_t *ata_ctlp,
20911709Smlf ata_drv_t *ata_drvp,
20921709Smlf ata_pkt_t *ata_pktp)
20931709Smlf {
20941709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
20951709Smlf int rc;
20961709Smlf
20971709Smlf rc = ata_disk_start_common(ata_ctlp, ata_drvp, ata_pktp);
20981709Smlf
20991709Smlf if (!rc)
21001709Smlf return (ATA_FSM_RC_BUSY);
21011709Smlf /*
21021709Smlf * This next one sets the controller in motion
21031709Smlf */
21041709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ata_pktp->ap_cmd);
21051709Smlf
21061709Smlf /* wait for the busy bit to settle */
21074852Smlf ata_nsecwait(400);
21081709Smlf
21091709Smlf return (ATA_FSM_RC_OKAY);
21101709Smlf }
21111709Smlf
21121709Smlf
21131709Smlf
21141709Smlf
21151709Smlf /*
21161709Smlf *
21171709Smlf * Start a PIO data-out ATA command:
21181709Smlf *
21191709Smlf */
21201709Smlf
21211709Smlf static int
ata_disk_start_pio_out(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)21221709Smlf ata_disk_start_pio_out(
21231709Smlf ata_ctl_t *ata_ctlp,
21241709Smlf ata_drv_t *ata_drvp,
21251709Smlf ata_pkt_t *ata_pktp)
21261709Smlf {
21271709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
21281709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
21291709Smlf int rc;
21301709Smlf
21311709Smlf ata_pktp->ap_wrt_count = 0;
21321709Smlf
21331709Smlf rc = ata_disk_start_common(ata_ctlp, ata_drvp, ata_pktp);
21341709Smlf
21351709Smlf if (!rc)
21361709Smlf return (ATA_FSM_RC_BUSY);
21371709Smlf /*
21381709Smlf * This next one sets the controller in motion
21391709Smlf */
21401709Smlf ddi_put8(io_hdl1, ata_ctlp->ac_cmd, ata_pktp->ap_cmd);
21411709Smlf
21421709Smlf /* wait for the busy bit to settle */
21434852Smlf ata_nsecwait(400);
21441709Smlf
21451709Smlf /*
21461709Smlf * Wait for the drive to assert DRQ to send the first chunk
21471709Smlf * of data. Have to busy wait because there's no interrupt for
21481709Smlf * the first chunk. This sucks (a lot of cycles) if the
21491709Smlf * drive responds too slowly or if the wait loop granularity
21501709Smlf * is too large. It's really bad if the drive is defective and
21511709Smlf * the loop times out.
21521709Smlf */
21531709Smlf
21541709Smlf if (!ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2,
21551709Smlf ATS_DRQ, ATS_BSY, /* okay */
21561709Smlf ATS_ERR, ATS_BSY, /* cmd failed */
21571709Smlf ATS_DF, ATS_BSY, /* drive failed */
21581709Smlf 4000000)) {
21591709Smlf ADBG_WARN(("ata_disk_start_pio_out: no DRQ\n"));
21601709Smlf ata_pktp->ap_flags |= AP_ERROR;
21611709Smlf return (ATA_FSM_RC_INTR);
21621709Smlf }
21631709Smlf
21641709Smlf /*
21651709Smlf * Tell the upper layer to fake a hardware interrupt which
21661709Smlf * actually causes the first segment to be written to the drive.
21671709Smlf */
21681709Smlf return (ATA_FSM_RC_INTR);
21691709Smlf }
21701709Smlf
21711709Smlf
21721709Smlf
21731709Smlf /*
21741709Smlf *
21751709Smlf * packet complete callback routine
21761709Smlf *
21771709Smlf */
21781709Smlf
21791709Smlf static void
ata_disk_complete(ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp,int do_callback)21801709Smlf ata_disk_complete(
21811709Smlf ata_drv_t *ata_drvp,
21821709Smlf ata_pkt_t *ata_pktp,
21831709Smlf int do_callback)
21841709Smlf {
21851709Smlf struct ata_id *aidp = &ata_drvp->ad_id;
21861709Smlf cmpkt_t *pktp;
21871709Smlf
21881709Smlf ADBG_TRACE(("ata_disk_complete entered\n"));
21891709Smlf ADBG_TRANSPORT(("ata_disk_complete: pkt = 0x%p\n", ata_pktp));
21901709Smlf
21911709Smlf pktp = APKT2CPKT(ata_pktp);
21921709Smlf
21931709Smlf /* update resid */
21941709Smlf
21951709Smlf pktp->cp_resid = ata_pktp->ap_resid;
21961709Smlf
21971709Smlf if (ata_pktp->ap_flags & AP_ERROR) {
21981709Smlf
21991709Smlf pktp->cp_reason = CPS_CHKERR;
22001709Smlf
22011709Smlf if (ata_pktp->ap_error & ATE_BBK_ICRC) {
22021709Smlf if (IS_ATA_VERSION_GE(aidp, 4))
22031709Smlf ata_pktp->ap_scb = DERR_ICRC;
22041709Smlf else
22051709Smlf ata_pktp->ap_scb = DERR_BBK;
22061709Smlf } else if (ata_pktp->ap_error & ATE_UNC)
22071709Smlf ata_pktp->ap_scb = DERR_UNC;
22081709Smlf else if (ata_pktp->ap_error & ATE_IDNF)
22091709Smlf ata_pktp->ap_scb = DERR_IDNF;
22101709Smlf else if (ata_pktp->ap_error & ATE_TKONF)
22111709Smlf ata_pktp->ap_scb = DERR_TKONF;
22121709Smlf else if (ata_pktp->ap_error & ATE_AMNF)
22131709Smlf ata_pktp->ap_scb = DERR_AMNF;
22141709Smlf else if (ata_pktp->ap_status & ATS_BSY)
22151709Smlf ata_pktp->ap_scb = DERR_BUSY;
22161709Smlf else if (ata_pktp->ap_status & ATS_DF)
22171709Smlf ata_pktp->ap_scb = DERR_DWF;
22181709Smlf else /* any unknown error */
22191709Smlf ata_pktp->ap_scb = DERR_ABORT;
22201709Smlf } else if (ata_pktp->ap_flags &
22211709Smlf (AP_ABORT|AP_TIMEOUT|AP_BUS_RESET)) {
22221709Smlf
22231709Smlf pktp->cp_reason = CPS_CHKERR;
22241709Smlf ata_pktp->ap_scb = DERR_ABORT;
22251709Smlf } else {
22261709Smlf pktp->cp_reason = CPS_SUCCESS;
22271709Smlf ata_pktp->ap_scb = DERR_SUCCESS;
22281709Smlf }
22291709Smlf
22301709Smlf /* callback */
22311709Smlf if (do_callback)
22321709Smlf (*pktp->cp_callback)(pktp);
22331709Smlf }
22341709Smlf
22351709Smlf
22361709Smlf /*
22371709Smlf *
22381709Smlf * Interrupt callbacks
22391709Smlf *
22401709Smlf */
22411709Smlf
22421709Smlf
22431709Smlf /*
22441709Smlf *
22451709Smlf * ATA command, no data
22461709Smlf *
22471709Smlf */
22481709Smlf
22491709Smlf /* ARGSUSED */
22501709Smlf static int
ata_disk_intr(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)22511709Smlf ata_disk_intr(
22521709Smlf ata_ctl_t *ata_ctlp,
22531709Smlf ata_drv_t *ata_drvp,
22541709Smlf ata_pkt_t *ata_pktp)
22551709Smlf {
22561709Smlf uchar_t status;
22571709Smlf
22581709Smlf ADBG_TRACE(("ata_disk_intr entered\n"));
22591709Smlf ADBG_TRANSPORT(("ata_disk_intr: pkt = 0x%p\n", ata_pktp));
22601709Smlf
22611709Smlf status = ata_get_status_clear_intr(ata_ctlp, ata_pktp);
22621709Smlf
22631709Smlf ASSERT((status & (ATS_BSY | ATS_DRQ)) == 0);
22641709Smlf
22651709Smlf /*
22661709Smlf * check for errors
22671709Smlf */
22681709Smlf
22691709Smlf if (status & (ATS_DF | ATS_ERR)) {
22701709Smlf ADBG_WARN(("ata_disk_intr: status 0x%x error 0x%x\n", status,
22711709Smlf ddi_get8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_error)));
22721709Smlf ata_pktp->ap_flags |= AP_ERROR;
22731709Smlf }
22741709Smlf
22751709Smlf if (ata_pktp->ap_flags & AP_ERROR) {
22761709Smlf ata_pktp->ap_status = ddi_get8(ata_ctlp->ac_iohandle2,
22771709Smlf ata_ctlp->ac_altstatus);
22781709Smlf ata_pktp->ap_error = ddi_get8(ata_ctlp->ac_iohandle1,
22791709Smlf ata_ctlp->ac_error);
22801709Smlf }
22811709Smlf
22821709Smlf /* tell the upper layer this request is complete */
22831709Smlf return (ATA_FSM_RC_FINI);
22841709Smlf }
22851709Smlf
22861709Smlf
22871709Smlf /*
22881709Smlf *
22891709Smlf * ATA command, PIO data in
22901709Smlf *
22911709Smlf */
22921709Smlf
22931709Smlf /* ARGSUSED */
22941709Smlf static int
ata_disk_intr_pio_in(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)22951709Smlf ata_disk_intr_pio_in(
22961709Smlf ata_ctl_t *ata_ctlp,
22971709Smlf ata_drv_t *ata_drvp,
22981709Smlf ata_pkt_t *ata_pktp)
22991709Smlf {
23001709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
23011709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
23021709Smlf uchar_t status;
23031709Smlf
23041709Smlf ADBG_TRACE(("ata_disk_pio_in entered\n"));
23051709Smlf ADBG_TRANSPORT(("ata_disk_pio_in: pkt = 0x%p\n", ata_pktp));
23061709Smlf
23071709Smlf /*
23081709Smlf * first make certain DRQ is asserted (and no errors)
23091709Smlf */
23101709Smlf (void) ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2,
23111709Smlf ATS_DRQ, ATS_BSY, ATS_ERR, ATS_BSY, ATS_DF, ATS_BSY,
23121709Smlf 4000000);
23131709Smlf
23141709Smlf status = ata_get_status_clear_intr(ata_ctlp, ata_pktp);
23151709Smlf
23161709Smlf if (status & ATS_BSY) {
23171709Smlf ADBG_WARN(("ata_disk_pio_in: BUSY\n"));
23181709Smlf ata_pktp->ap_flags |= AP_ERROR;
23191709Smlf ata_pktp->ap_status = ddi_get8(io_hdl2, ata_ctlp->ac_altstatus);
23201709Smlf ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
23211709Smlf return (ATA_FSM_RC_BUSY);
23221709Smlf }
23231709Smlf
23241709Smlf /*
23251709Smlf * record any errors
23261709Smlf */
23271709Smlf if ((status & (ATS_DRQ | ATS_DF | ATS_ERR)) != ATS_DRQ) {
23281709Smlf ADBG_WARN(("ata_disk_pio_in: status 0x%x error 0x%x\n",
23291709Smlf status, ddi_get8(io_hdl1, ata_ctlp->ac_error)));
23301709Smlf ata_pktp->ap_flags |= AP_ERROR;
23311709Smlf ata_pktp->ap_status = ddi_get8(io_hdl2, ata_ctlp->ac_altstatus);
23321709Smlf ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
23331709Smlf }
23341709Smlf
23351709Smlf /*
23361709Smlf * read the next chunk of data (if any)
23371709Smlf */
23381709Smlf if (status & ATS_DRQ) {
23391709Smlf ata_disk_pio_xfer_data_in(ata_ctlp, ata_pktp);
23401709Smlf }
23411709Smlf
23421709Smlf /*
23431709Smlf * If that was the last chunk, wait for the device to clear DRQ
23441709Smlf */
23451709Smlf if (ata_pktp->ap_resid == 0) {
23461709Smlf if (ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2,
23471709Smlf 0, (ATS_DRQ | ATS_BSY), 4000000)) {
23481709Smlf /* tell the upper layer this request is complete */
23491709Smlf return (ATA_FSM_RC_FINI);
23501709Smlf }
23511709Smlf
23521709Smlf ADBG_WARN(("ata_disk_pio_in: DRQ stuck\n"));
23531709Smlf ata_pktp->ap_flags |= AP_ERROR;
23541709Smlf ata_pktp->ap_status = ddi_get8(io_hdl2, ata_ctlp->ac_altstatus);
23551709Smlf ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
23561709Smlf }
23571709Smlf
23581709Smlf /*
23591709Smlf * check for errors
23601709Smlf */
23611709Smlf if (ata_pktp->ap_flags & AP_ERROR) {
23621709Smlf return (ATA_FSM_RC_FINI);
23631709Smlf }
23641709Smlf
23651709Smlf /*
23661709Smlf * If the read command isn't done yet,
23671709Smlf * wait for the next interrupt.
23681709Smlf */
23691709Smlf ADBG_TRACE(("ata_disk_pio_in: partial\n"));
23701709Smlf return (ATA_FSM_RC_OKAY);
23711709Smlf }
23721709Smlf
23731709Smlf
23741709Smlf
23751709Smlf /*
23761709Smlf *
23771709Smlf * ATA command, PIO data out
23781709Smlf *
23791709Smlf */
23801709Smlf
23811709Smlf /* ARGSUSED */
23821709Smlf static int
ata_disk_intr_pio_out(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)23831709Smlf ata_disk_intr_pio_out(
23841709Smlf ata_ctl_t *ata_ctlp,
23851709Smlf ata_drv_t *ata_drvp,
23861709Smlf ata_pkt_t *ata_pktp)
23871709Smlf {
23881709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
23891709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
23901709Smlf int tmp_count = ata_pktp->ap_wrt_count;
23911709Smlf uchar_t status;
23921709Smlf
23931709Smlf /*
23941709Smlf * clear the IRQ
23951709Smlf */
23961709Smlf status = ata_get_status_clear_intr(ata_ctlp, ata_pktp);
23971709Smlf
23981709Smlf ADBG_TRACE(("ata_disk_intr_pio_out entered\n"));
23991709Smlf ADBG_TRANSPORT(("ata_disk_intr_pio_out: pkt = 0x%p\n", ata_pktp));
24001709Smlf
24011709Smlf ASSERT(!(status & ATS_BSY));
24021709Smlf
24031709Smlf
24041709Smlf /*
24051709Smlf * check for errors
24061709Smlf */
24071709Smlf
24081709Smlf if (status & (ATS_DF | ATS_ERR)) {
24091709Smlf ADBG_WARN(("ata_disk_intr_pio_out: status 0x%x error 0x%x\n",
24101709Smlf status, ddi_get8(io_hdl1, ata_ctlp->ac_error)));
24111709Smlf ata_pktp->ap_flags |= AP_ERROR;
24121709Smlf ata_pktp->ap_status = ddi_get8(io_hdl2, ata_ctlp->ac_altstatus);
24131709Smlf ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
24141709Smlf /* tell the upper layer this request is complete */
24151709Smlf return (ATA_FSM_RC_FINI);
24161709Smlf }
24171709Smlf
24181709Smlf
24191709Smlf /*
24201709Smlf * last write was okay, bump the ptr and
24211709Smlf * decr the resid count
24221709Smlf */
24231709Smlf ata_pktp->ap_v_addr += tmp_count;
24241709Smlf ata_pktp->ap_resid -= tmp_count;
24251709Smlf
24261709Smlf /*
24271709Smlf * check for final interrupt on write command
24281709Smlf */
24297671SZhongyan.Gu@Sun.COM if (ata_pktp->ap_resid == 0) {
24301709Smlf /* tell the upper layer this request is complete */
24311709Smlf return (ATA_FSM_RC_FINI);
24321709Smlf }
24331709Smlf
24341709Smlf /*
24351709Smlf * Perform the next data transfer
24361709Smlf *
24371709Smlf * First make certain DRQ is asserted and no error status.
24381709Smlf * (I'm not certain but I think some drives might deassert BSY
24391709Smlf * before asserting DRQ. This extra ata_wait3() will
24401709Smlf * compensate for such drives).
24411709Smlf *
24421709Smlf */
24431709Smlf (void) ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2,
24441709Smlf ATS_DRQ, ATS_BSY, ATS_ERR, ATS_BSY, ATS_DF, ATS_BSY, 4000000);
24451709Smlf
24461709Smlf status = ddi_get8(io_hdl2, ata_ctlp->ac_altstatus);
24471709Smlf
24481709Smlf if (status & ATS_BSY) {
24491709Smlf /* this should never happen */
24501709Smlf ADBG_WARN(("ata_disk_intr_pio_out: BUSY\n"));
24511709Smlf ata_pktp->ap_flags |= AP_ERROR;
24521709Smlf ata_pktp->ap_status = ddi_get8(io_hdl2, ata_ctlp->ac_altstatus);
24531709Smlf ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
24541709Smlf return (ATA_FSM_RC_BUSY);
24551709Smlf }
24561709Smlf
24571709Smlf /*
24581709Smlf * bailout if any errors
24591709Smlf */
24601709Smlf if ((status & (ATS_DRQ | ATS_DF | ATS_ERR)) != ATS_DRQ) {
24611709Smlf ADBG_WARN(("ata_disk_pio_out: status 0x%x error 0x%x\n",
24621709Smlf status, ddi_get8(io_hdl1, ata_ctlp->ac_error)));
24631709Smlf ata_pktp->ap_flags |= AP_ERROR;
24641709Smlf ata_pktp->ap_status = ddi_get8(io_hdl2, ata_ctlp->ac_altstatus);
24651709Smlf ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
24661709Smlf return (ATA_FSM_RC_FINI);
24671709Smlf }
24681709Smlf
24691709Smlf /*
24701709Smlf * write the next chunk of data
24711709Smlf */
24721709Smlf ADBG_TRACE(("ata_disk_intr_pio_out: write xfer\n"));
24731709Smlf ata_disk_pio_xfer_data_out(ata_ctlp, ata_pktp);
24741709Smlf
24751709Smlf /*
24761709Smlf * Wait for the next interrupt before checking the transfer
24771709Smlf * status and adjusting the transfer count.
24781709Smlf *
24791709Smlf */
24801709Smlf return (ATA_FSM_RC_OKAY);
24811709Smlf }
24821709Smlf
24831709Smlf
24841709Smlf /*
24851709Smlf *
24861709Smlf * ATA command, DMA data in/out
24871709Smlf *
24881709Smlf */
24891709Smlf
24901709Smlf static int
ata_disk_intr_dma(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)24911709Smlf ata_disk_intr_dma(
24921709Smlf ata_ctl_t *ata_ctlp,
24931709Smlf ata_drv_t *ata_drvp,
24941709Smlf ata_pkt_t *ata_pktp)
24951709Smlf {
24961709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
24971709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
24981709Smlf uchar_t status;
24991709Smlf
25001709Smlf ADBG_TRACE(("ata_disk_intr_dma entered\n"));
25011709Smlf ADBG_TRANSPORT(("ata_disk_intr_dma: pkt = 0x%p\n", ata_pktp));
25021709Smlf
25031709Smlf /*
25041709Smlf * halt the DMA engine
25051709Smlf */
25061709Smlf ata_pciide_dma_stop(ata_ctlp);
25071709Smlf
25081709Smlf /*
25091709Smlf * wait for the device to clear DRQ
25101709Smlf */
25111709Smlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2,
25121709Smlf 0, (ATS_DRQ | ATS_BSY), 4000000)) {
25131709Smlf ADBG_WARN(("ata_disk_intr_dma: DRQ stuck\n"));
25141709Smlf ata_pktp->ap_flags |= AP_ERROR;
25151709Smlf ata_pktp->ap_status = ddi_get8(io_hdl2, ata_ctlp->ac_altstatus);
25161709Smlf ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
25171709Smlf return (ATA_FSM_RC_BUSY);
25181709Smlf }
25191709Smlf
25201709Smlf /*
25211709Smlf * get the status and clear the IRQ, and check for DMA error
25221709Smlf */
25231709Smlf status = ata_get_status_clear_intr(ata_ctlp, ata_pktp);
25241709Smlf
25251709Smlf /*
25261709Smlf * check for drive errors
25271709Smlf */
25281709Smlf
25291709Smlf if (status & (ATS_DF | ATS_ERR)) {
25301709Smlf ADBG_WARN(("ata_disk_intr_dma: status 0x%x error 0x%x\n",
25311709Smlf status, ddi_get8(io_hdl1, ata_ctlp->ac_error)));
25321709Smlf ata_pktp->ap_flags |= AP_ERROR;
25331709Smlf ata_pktp->ap_status = ddi_get8(io_hdl2, ata_ctlp->ac_altstatus);
25341709Smlf ata_pktp->ap_error = ddi_get8(io_hdl1, ata_ctlp->ac_error);
25351709Smlf }
25361709Smlf
25371709Smlf /*
25381709Smlf * If there was a drive or DMA error, compute a resid count
25391709Smlf */
25401709Smlf if (ata_pktp->ap_flags & AP_ERROR) {
25411709Smlf /*
25421709Smlf * grab the last sector address from the drive regs
25431709Smlf * and use that to compute the resid
25441709Smlf */
25451709Smlf ata_disk_get_resid(ata_ctlp, ata_drvp, ata_pktp);
25461709Smlf } else {
25471709Smlf ata_pktp->ap_resid = 0;
25481709Smlf }
25491709Smlf
25501709Smlf /* tell the upper layer this request is complete */
25511709Smlf return (ATA_FSM_RC_FINI);
25521709Smlf }
25531709Smlf
25541709Smlf
25551709Smlf /*
25561709Smlf *
25571709Smlf * Low level PIO routine that transfers data from the drive
25581709Smlf *
25591709Smlf */
25601709Smlf
25611709Smlf static void
ata_disk_pio_xfer_data_in(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp)25621709Smlf ata_disk_pio_xfer_data_in(
25631709Smlf ata_ctl_t *ata_ctlp,
25641709Smlf ata_pkt_t *ata_pktp)
25651709Smlf {
25661709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
25671709Smlf int count;
25681709Smlf
25691709Smlf count = min(ata_pktp->ap_resid,
25701709Smlf ata_pktp->ap_bytes_per_block);
25711709Smlf
25721709Smlf ADBG_TRANSPORT(("ata_disk_pio_xfer_data_in: 0x%x bytes, addr = 0x%p\n",
25731709Smlf count, ata_pktp->ap_v_addr));
25741709Smlf
25751709Smlf /*
25761709Smlf * read count bytes
25771709Smlf */
25781709Smlf
25791709Smlf ASSERT(count != 0);
25801709Smlf
25811709Smlf ddi_rep_get16(io_hdl1, (ushort_t *)ata_pktp->ap_v_addr,
25821709Smlf ata_ctlp->ac_data, (count >> 1), DDI_DEV_NO_AUTOINCR);
25831709Smlf
25841709Smlf /* wait for the busy bit to settle */
25854852Smlf ata_nsecwait(400);
25861709Smlf
25871709Smlf /*
25881709Smlf * this read command completed okay, bump the ptr and
25891709Smlf * decr the resid count now.
25901709Smlf */
25911709Smlf ata_pktp->ap_v_addr += count;
25921709Smlf ata_pktp->ap_resid -= count;
25931709Smlf }
25941709Smlf
25951709Smlf
25961709Smlf /*
25971709Smlf *
25981709Smlf * Low level PIO routine that transfers data to the drive
25991709Smlf *
26001709Smlf */
26011709Smlf
26021709Smlf static void
ata_disk_pio_xfer_data_out(ata_ctl_t * ata_ctlp,ata_pkt_t * ata_pktp)26031709Smlf ata_disk_pio_xfer_data_out(
26041709Smlf ata_ctl_t *ata_ctlp,
26051709Smlf ata_pkt_t *ata_pktp)
26061709Smlf {
26071709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
26081709Smlf int count;
26091709Smlf
26101709Smlf count = min(ata_pktp->ap_resid,
26111709Smlf ata_pktp->ap_bytes_per_block);
26121709Smlf
26131709Smlf ADBG_TRANSPORT(("ata_disk_pio_xfer_data_out: 0x%x bytes, addr = 0x%p\n",
26141709Smlf count, ata_pktp->ap_v_addr));
26151709Smlf
26161709Smlf /*
26171709Smlf * read or write count bytes
26181709Smlf */
26191709Smlf
26201709Smlf ASSERT(count != 0);
26211709Smlf
26221709Smlf ddi_rep_put16(io_hdl1, (ushort_t *)ata_pktp->ap_v_addr,
26231709Smlf ata_ctlp->ac_data, (count >> 1), DDI_DEV_NO_AUTOINCR);
26241709Smlf
26251709Smlf /* wait for the busy bit to settle */
26264852Smlf ata_nsecwait(400);
26271709Smlf
26281709Smlf /*
26291709Smlf * save the count here so I can correctly adjust
26301709Smlf * the ap_v_addr and ap_resid values at the next
26311709Smlf * interrupt.
26321709Smlf */
26331709Smlf ata_pktp->ap_wrt_count = count;
26341709Smlf }
26351709Smlf
26361709Smlf
26371709Smlf /*
26381709Smlf *
26391709Smlf * ATA Initialize Device Parameters (aka Set Params) command
26401709Smlf *
26411709Smlf * If the drive was put in some sort of CHS extended/logical geometry
26421709Smlf * mode by the BIOS, this function will reset it to its "native"
26431709Smlf * CHS geometry. This ensures that we don't run into any sort of
26441709Smlf * 1024 cylinder (or 65535 cylinder) limitation that may have been
26451709Smlf * created by a BIOS (or users) that chooses a bogus translated geometry.
26461709Smlf */
26471709Smlf
26481709Smlf static int
ata_disk_initialize_device_parameters(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp)26491709Smlf ata_disk_initialize_device_parameters(
26501709Smlf ata_ctl_t *ata_ctlp,
26511709Smlf ata_drv_t *ata_drvp)
26521709Smlf {
26531709Smlf int rc;
26541709Smlf
26551709Smlf rc = ata_command(ata_ctlp, ata_drvp, FALSE, FALSE,
26561709Smlf ata_disk_init_dev_parm_wait,
26571709Smlf ATC_SETPARAM,
26581709Smlf 0, /* feature n/a */
26591709Smlf ata_drvp->ad_phsec, /* max sector (1-based) */
26601709Smlf 0, /* sector n/a */
26611709Smlf (ata_drvp->ad_phhd -1), /* max head (0-based) */
26621709Smlf 0, /* cyl_low n/a */
26631709Smlf 0); /* cyl_hi n/a */
26641709Smlf
26653446Smrj if (rc)
26661709Smlf return (TRUE);
26671709Smlf
26681709Smlf ADBG_ERROR(("ata_init_dev_parms: failed\n"));
26691709Smlf return (FALSE);
26701709Smlf }
26711709Smlf
26721709Smlf
26731709Smlf
26741709Smlf /*
26751709Smlf *
26761709Smlf * create fake inquiry data for DADA interface
26771709Smlf *
26781709Smlf */
26791709Smlf
26801709Smlf static void
ata_disk_fake_inquiry(ata_drv_t * ata_drvp)26811709Smlf ata_disk_fake_inquiry(
26821709Smlf ata_drv_t *ata_drvp)
26831709Smlf {
26841709Smlf struct ata_id *ata_idp = &ata_drvp->ad_id;
26851709Smlf struct scsi_inquiry *inqp = &ata_drvp->ad_inquiry;
26861709Smlf
26871709Smlf ADBG_TRACE(("ata_disk_fake_inquiry entered\n"));
26881709Smlf
26891709Smlf if (ata_idp->ai_config & ATA_ID_REM_DRV) /* ide removable bit */
26901709Smlf inqp->inq_rmb = 1; /* scsi removable bit */
26911709Smlf
26921709Smlf (void) strncpy(inqp->inq_vid, "Gen-ATA ", sizeof (inqp->inq_vid));
26931709Smlf inqp->inq_dtype = DTYPE_DIRECT;
26941709Smlf inqp->inq_qual = DPQ_POSSIBLE;
26951709Smlf
26961709Smlf (void) strncpy(inqp->inq_pid, ata_idp->ai_model,
26971709Smlf sizeof (inqp->inq_pid));
26981709Smlf (void) strncpy(inqp->inq_revision, ata_idp->ai_fw,
26991709Smlf sizeof (inqp->inq_revision));
27001709Smlf }
27011709Smlf
27021709Smlf #define LOOP_COUNT 10000
27031709Smlf
27041709Smlf
27051709Smlf /*
27061709Smlf *
27071709Smlf * ATA Set Multiple Mode
27081709Smlf *
27091709Smlf */
27101709Smlf
27111709Smlf static int
ata_disk_set_multiple(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp)27121709Smlf ata_disk_set_multiple(
27131709Smlf ata_ctl_t *ata_ctlp,
27141709Smlf ata_drv_t *ata_drvp)
27151709Smlf {
27161709Smlf int rc;
27171709Smlf
27181709Smlf rc = ata_command(ata_ctlp, ata_drvp, TRUE, FALSE,
27191709Smlf ata_disk_set_mult_wait,
27201709Smlf ATC_SETMULT,
27211709Smlf 0, /* feature n/a */
27221709Smlf ata_drvp->ad_block_factor, /* count */
27231709Smlf 0, /* sector n/a */
27241709Smlf 0, /* head n/a */
27251709Smlf 0, /* cyl_low n/a */
27261709Smlf 0); /* cyl_hi n/a */
27271709Smlf
27281709Smlf if (rc) {
27291709Smlf return (TRUE);
27301709Smlf }
27311709Smlf
27321709Smlf ADBG_ERROR(("ata_disk_set_multiple: failed\n"));
27331709Smlf return (FALSE);
27341709Smlf }
27351709Smlf
27361709Smlf
27371709Smlf /*
27381709Smlf *
27391709Smlf * ATA Identify Device command
27401709Smlf *
27411709Smlf */
27421709Smlf
27431709Smlf int
ata_disk_id(ddi_acc_handle_t io_hdl1,caddr_t ioaddr1,ddi_acc_handle_t io_hdl2,caddr_t ioaddr2,struct ata_id * ata_idp)27441709Smlf ata_disk_id(
27451709Smlf ddi_acc_handle_t io_hdl1,
27461709Smlf caddr_t ioaddr1,
27471709Smlf ddi_acc_handle_t io_hdl2,
27481709Smlf caddr_t ioaddr2,
27491709Smlf struct ata_id *ata_idp)
27501709Smlf {
27511709Smlf int rc;
27521709Smlf
27531709Smlf ADBG_TRACE(("ata_disk_id entered\n"));
27541709Smlf
27551709Smlf rc = ata_id_common(ATC_ID_DEVICE, TRUE, io_hdl1, ioaddr1, io_hdl2,
27561709Smlf ioaddr2, ata_idp);
27571709Smlf
27581709Smlf if (!rc)
27591709Smlf return (FALSE);
27601709Smlf
27611709Smlf /*
27621709Smlf * If the disk is a CF/Microdrive that works under ATA mode
27631709Smlf * through CF<->ATA adapters, identify it as an ATA device
27641709Smlf * and a non removable media.
27651709Smlf */
27661709Smlf if (ata_idp->ai_config == ATA_ID_COMPACT_FLASH) {
27671709Smlf ata_idp->ai_config = ATA_ID_CF_TO_ATA;
27681709Smlf }
27691709Smlf
27701709Smlf if ((ata_idp->ai_config & ATAC_ATA_TYPE_MASK) != ATAC_ATA_TYPE)
27711709Smlf return (FALSE);
27721709Smlf
27731709Smlf if (ata_idp->ai_heads == 0 || ata_idp->ai_sectors == 0) {
27741709Smlf return (FALSE);
27751709Smlf }
27761709Smlf
27771709Smlf return (TRUE);
27781709Smlf }
27791709Smlf
27801709Smlf static daddr_t
ata_last_block_xferred_chs(ata_drv_t * ata_drvp)27811709Smlf ata_last_block_xferred_chs(ata_drv_t *ata_drvp)
27821709Smlf {
27831709Smlf ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
27841709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
27851709Smlf uchar_t drvheads = ata_drvp->ad_phhd;
27861709Smlf uchar_t drvsectors = ata_drvp->ad_phsec;
27871709Smlf uchar_t sector;
27881709Smlf uchar_t head;
27891709Smlf uchar_t low_cyl;
27901709Smlf uchar_t hi_cyl;
27911709Smlf daddr_t lbastop;
27921709Smlf
27931709Smlf sector = ddi_get8(io_hdl1, ata_ctlp->ac_sect);
27941709Smlf head = ddi_get8(io_hdl1, ata_ctlp->ac_drvhd) & 0xf;
27951709Smlf low_cyl = ddi_get8(io_hdl1, ata_ctlp->ac_lcyl);
27961709Smlf hi_cyl = ddi_get8(io_hdl1, ata_ctlp->ac_hcyl);
27971709Smlf
27981709Smlf lbastop = low_cyl;
27991709Smlf lbastop |= (uint_t)hi_cyl << 8;
28001709Smlf lbastop *= (uint_t)drvheads;
28011709Smlf lbastop += (uint_t)head;
28021709Smlf lbastop *= (uint_t)drvsectors;
28031709Smlf lbastop += (uint_t)sector - 1;
28041709Smlf return (lbastop);
28051709Smlf }
28061709Smlf
28071709Smlf static daddr_t
ata_last_block_xferred_lba28(ata_ctl_t * ata_ctlp)28081709Smlf ata_last_block_xferred_lba28(ata_ctl_t *ata_ctlp)
28091709Smlf {
28101709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
28111709Smlf daddr_t lbastop;
28121709Smlf
28131709Smlf lbastop = ddi_get8(io_hdl1, ata_ctlp->ac_drvhd) & 0xf;
28141709Smlf lbastop <<= 8;
28151709Smlf lbastop += ddi_get8(io_hdl1, ata_ctlp->ac_hcyl);
28161709Smlf lbastop <<= 8;
28171709Smlf lbastop += ddi_get8(io_hdl1, ata_ctlp->ac_lcyl);
28181709Smlf lbastop <<= 8;
28191709Smlf lbastop += ddi_get8(io_hdl1, ata_ctlp->ac_sect);
28201709Smlf return (lbastop);
28211709Smlf }
28221709Smlf
28231709Smlf static daddr_t
ata_last_block_xferred_lba48(ata_ctl_t * ata_ctlp)28241709Smlf ata_last_block_xferred_lba48(ata_ctl_t *ata_ctlp)
28251709Smlf {
28261709Smlf ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
28271709Smlf ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
28281709Smlf daddr_t lbastop;
28291709Smlf
28301709Smlf /* turn on HOB and read the high-order 24 bits */
28311709Smlf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, (ATDC_D3 | ATDC_HOB));
28321709Smlf lbastop = ddi_get8(io_hdl1, ata_ctlp->ac_hcyl);
28331709Smlf lbastop <<= 8;
28341709Smlf lbastop += ddi_get8(io_hdl1, ata_ctlp->ac_lcyl);
28351709Smlf lbastop <<= 8;
28361709Smlf lbastop += ddi_get8(io_hdl1, ata_ctlp->ac_sect);
28371709Smlf lbastop <<= 8;
28381709Smlf
28391709Smlf /* Turn off HOB and read the low-order 24-bits */
28401709Smlf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, (ATDC_D3));
28411709Smlf lbastop += ddi_get8(io_hdl1, ata_ctlp->ac_hcyl);
28421709Smlf lbastop <<= 8;
28431709Smlf lbastop += ddi_get8(io_hdl1, ata_ctlp->ac_lcyl);
28441709Smlf lbastop <<= 8;
28451709Smlf lbastop += ddi_get8(io_hdl1, ata_ctlp->ac_sect);
28461709Smlf return (lbastop);
28471709Smlf }
28481709Smlf
28491709Smlf
28501709Smlf /*
28511709Smlf *
28521709Smlf * Need to compute a value for ap_resid so that cp_resid can
28531709Smlf * be set by ata_disk_complete(). The cp_resid var is actually
28541709Smlf * misnamed. It's actually the offset to the block in which the
28551709Smlf * error occurred not the number of bytes transferred to the device.
28561709Smlf * At least that's how dadk actually uses the cp_resid when reporting
28571709Smlf * an error. In other words the sector that had the error and the
28581709Smlf * number of bytes transferred don't always indicate the same offset.
28591709Smlf * On top of that, when doing DMA transfers there's actually no
28601709Smlf * way to determine how many bytes have been transferred by the DMA
28611709Smlf * engine. On the other hand, the drive will report which sector
28621709Smlf * it faulted on. Using that address this routine computes the
28631709Smlf * number of residual bytes beyond that point which probably weren't
28641709Smlf * written to the drive (the drive is allowed to re-order sector
28651709Smlf * writes but on an ATA disk there's no way to deal with that
28661709Smlf * complication; in other words, the resid value calculated by
28671709Smlf * this routine is as good as we can manage).
28681709Smlf */
28691709Smlf
28701709Smlf static void
ata_disk_get_resid(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)28711709Smlf ata_disk_get_resid(
28721709Smlf ata_ctl_t *ata_ctlp,
28731709Smlf ata_drv_t *ata_drvp,
28741709Smlf ata_pkt_t *ata_pktp)
28751709Smlf {
28761709Smlf uint_t lba_start;
28771709Smlf uint_t lba_stop;
28781709Smlf uint_t resid_bytes;
28791709Smlf uint_t resid_sectors;
28801709Smlf
28811709Smlf lba_start = ata_pktp->ap_startsec;
28821709Smlf
28831709Smlf if (ata_drvp->ad_flags & AD_EXT48)
28841709Smlf lba_stop = ata_last_block_xferred_lba48(ata_ctlp);
28851709Smlf else if (ata_drvp->ad_drive_bits & ATDH_LBA)
28861709Smlf lba_stop = ata_last_block_xferred_lba28(ata_ctlp);
28871709Smlf else /* CHS mode */
28881709Smlf lba_stop = ata_last_block_xferred_chs(ata_drvp);
28891709Smlf
28901709Smlf resid_sectors = lba_start + ata_pktp->ap_count - lba_stop;
28911709Smlf resid_bytes = resid_sectors << SCTRSHFT;
28921709Smlf
28931709Smlf ADBG_TRACE(("ata_disk_get_resid start 0x%x cnt 0x%x stop 0x%x\n",
28941709Smlf lba_start, ata_pktp->ap_count, lba_stop));
28951709Smlf ata_pktp->ap_resid = resid_bytes;
28961709Smlf }
28971709Smlf
28981709Smlf
28991709Smlf
29001709Smlf /*
29011709Smlf * Removable media commands *
29021709Smlf */
29031709Smlf
29041709Smlf
29051709Smlf
29061709Smlf /*
29071709Smlf * get the media status
29081709Smlf *
29091709Smlf * NOTE: the error handling case probably isn't correct but it
29101709Smlf * will have to do until someone gives me a drive to test this on.
29111709Smlf */
29121709Smlf static int
ata_disk_state(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)29131709Smlf ata_disk_state(
29141709Smlf ata_ctl_t *ata_ctlp,
29151709Smlf ata_drv_t *ata_drvp,
29161709Smlf ata_pkt_t *ata_pktp)
29171709Smlf {
29181709Smlf int *statep = (int *)ata_pktp->ap_v_addr;
29191709Smlf uchar_t err;
29201709Smlf
29211709Smlf ADBG_TRACE(("ata_disk_state\n"));
29221709Smlf if (ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, 5 * 1000000,
29231709Smlf ATC_DOOR_LOCK, 0, 0, 0, 0, 0, 0)) {
29241709Smlf *statep = DKIO_INSERTED;
29251709Smlf return (ATA_FSM_RC_FINI);
29261709Smlf }
29271709Smlf
29281709Smlf err = ddi_get8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_error);
29291709Smlf if (err & ATE_NM)
29301709Smlf *statep = DKIO_EJECTED;
29311709Smlf else
29321709Smlf *statep = DKIO_NONE;
29331709Smlf
29341709Smlf return (ATA_FSM_RC_FINI);
29351709Smlf }
29361709Smlf
29371709Smlf /*
29381709Smlf * eject the media
29391709Smlf */
29401709Smlf
29411709Smlf static int
ata_disk_eject(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)29421709Smlf ata_disk_eject(
29431709Smlf ata_ctl_t *ata_ctlp,
29441709Smlf ata_drv_t *ata_drvp,
29451709Smlf ata_pkt_t *ata_pktp)
29461709Smlf {
29471709Smlf ADBG_TRACE(("ata_disk_eject\n"));
29481709Smlf if (ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, 5 * 1000000,
29491709Smlf ATC_EJECT, 0, 0, 0, 0, 0, 0)) {
29501709Smlf return (ATA_FSM_RC_FINI);
29511709Smlf }
29521709Smlf ata_pktp->ap_flags |= AP_ERROR;
29531709Smlf return (ATA_FSM_RC_FINI);
29541709Smlf }
29551709Smlf
29561709Smlf /*
29571709Smlf * lock the drive
29581709Smlf *
29591709Smlf */
29601709Smlf static int
ata_disk_lock(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)29611709Smlf ata_disk_lock(
29621709Smlf ata_ctl_t *ata_ctlp,
29631709Smlf ata_drv_t *ata_drvp,
29641709Smlf ata_pkt_t *ata_pktp)
29651709Smlf {
29661709Smlf ADBG_TRACE(("ata_disk_lock\n"));
29671709Smlf if (ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, 5 * 1000000,
29681709Smlf ATC_DOOR_LOCK, 0, 0, 0, 0, 0, 0)) {
29691709Smlf return (ATA_FSM_RC_FINI);
29701709Smlf }
29711709Smlf ata_pktp->ap_flags |= AP_ERROR;
29721709Smlf return (ATA_FSM_RC_FINI);
29731709Smlf }
29741709Smlf
29751709Smlf
29761709Smlf /*
29771709Smlf * unlock the drive
29781709Smlf *
29791709Smlf */
29801709Smlf static int
ata_disk_unlock(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)29811709Smlf ata_disk_unlock(
29821709Smlf ata_ctl_t *ata_ctlp,
29831709Smlf ata_drv_t *ata_drvp,
29841709Smlf ata_pkt_t *ata_pktp)
29851709Smlf {
29861709Smlf ADBG_TRACE(("ata_disk_unlock\n"));
29871709Smlf if (ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, 5 * 1000000,
29881709Smlf ATC_DOOR_UNLOCK, 0, 0, 0, 0, 0, 0)) {
29891709Smlf return (ATA_FSM_RC_FINI);
29901709Smlf }
29911709Smlf ata_pktp->ap_flags |= AP_ERROR;
29921709Smlf return (ATA_FSM_RC_FINI);
29931709Smlf }
29941709Smlf
29951709Smlf
29961709Smlf /*
29971709Smlf * put the drive into standby mode
29981709Smlf */
29991709Smlf static int
ata_disk_standby(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)30001709Smlf ata_disk_standby(
30011709Smlf ata_ctl_t *ata_ctlp,
30021709Smlf ata_drv_t *ata_drvp,
30031709Smlf ata_pkt_t *ata_pktp)
30041709Smlf {
30051709Smlf ADBG_TRACE(("ata_disk_standby\n"));
30061709Smlf if (ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, 5 * 1000000,
30071709Smlf ATC_STANDBY_IM, 0, 0, 0, 0, 0, 0)) {
30081709Smlf return (ATA_FSM_RC_FINI);
30091709Smlf }
30101709Smlf ata_pktp->ap_flags |= AP_ERROR;
30111709Smlf return (ATA_FSM_RC_FINI);
30121709Smlf }
30131709Smlf
30141709Smlf
30151709Smlf /*
30161709Smlf * Recalibrate
30171709Smlf *
30181709Smlf * Note the extra long timeout value. This is necessary in case
30191709Smlf * the drive was in standby mode and needs to spin up the media.
30201709Smlf *
30211709Smlf */
30221709Smlf static int
ata_disk_recalibrate(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)30231709Smlf ata_disk_recalibrate(
30241709Smlf ata_ctl_t *ata_ctlp,
30251709Smlf ata_drv_t *ata_drvp,
30261709Smlf ata_pkt_t *ata_pktp)
30271709Smlf {
30281709Smlf ADBG_TRACE(("ata_disk_recalibrate\n"));
30291709Smlf if (ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, 31 * 1000000,
30301709Smlf ATC_RECAL, 0, 0, 0, 0, 0, 0)) {
30311709Smlf return (ATA_FSM_RC_FINI);
30321709Smlf }
30331709Smlf ata_pktp->ap_flags |= AP_ERROR;
30341709Smlf return (ATA_FSM_RC_FINI);
30351709Smlf }
30361709Smlf
30371709Smlf /*
30381709Smlf * Copy a string of bytes that were obtained by Identify Device into a
30391709Smlf * string buffer provided by the caller.
30401709Smlf *
30411709Smlf * 1. Determine the amount to copy. This is the lesser of the
30421709Smlf * length of the source string or the space available in the user's
30431709Smlf * buffer.
30441709Smlf * 2. The true length of the source string is always returned to the
30451709Smlf * caller in the size field of the argument.
30461709Smlf * 3. Copy the string, add a terminating NUL character at the end.
30471709Smlf */
30481709Smlf
30491709Smlf static int
ata_copy_dk_ioc_string(intptr_t arg,char * source,int length,int flag)30501709Smlf ata_copy_dk_ioc_string(intptr_t arg, char *source, int length, int flag)
30511709Smlf {
30521709Smlf STRUCT_DECL(dadk_ioc_string, ds_arg);
30531709Smlf int destsize;
30541709Smlf char nulchar;
30551709Smlf caddr_t outp;
30561709Smlf
30571709Smlf /*
30581709Smlf * The ioctls that use this routine are only available to
30591709Smlf * the kernel.
30601709Smlf */
30611709Smlf if ((flag & FKIOCTL) == 0)
30621709Smlf return (EFAULT);
30631709Smlf
30641709Smlf STRUCT_INIT(ds_arg, flag & FMODELS);
30651709Smlf
30661709Smlf /* 1. determine size of user's buffer */
30671709Smlf if (ddi_copyin((caddr_t)arg, STRUCT_BUF(ds_arg), STRUCT_SIZE(ds_arg),
30681709Smlf flag))
30691709Smlf return (EFAULT);
30701709Smlf destsize = STRUCT_FGET(ds_arg, is_size);
30711709Smlf if (destsize > length + 1)
30721709Smlf destsize = length + 1;
30731709Smlf
30741709Smlf /*
30751709Smlf * 2. Return the copied length to the caller. Note: for
30761709Smlf * convenience, we actually copy the entire structure back out, not
30771709Smlf * just the length. We don't change the is_buf field, so this
30781709Smlf * shouldn't break anything.
30791709Smlf */
30801709Smlf STRUCT_FSET(ds_arg, is_size, length);
30811709Smlf if (ddi_copyout(STRUCT_BUF(ds_arg), (caddr_t)arg, STRUCT_SIZE(ds_arg),
30821709Smlf flag))
30831709Smlf return (EFAULT);
30841709Smlf
30851709Smlf /* 3. copy the string and add a NULL terminator */
30861709Smlf outp = STRUCT_FGETP(ds_arg, is_buf);
30871709Smlf if (ddi_copyout(source, outp, destsize - 1, flag))
30881709Smlf return (EFAULT);
30891709Smlf nulchar = '\0';
30901709Smlf if (ddi_copyout(&nulchar, outp + (destsize - 1), 1, flag))
30911709Smlf return (EFAULT);
30921709Smlf return (0);
30931709Smlf }
30941709Smlf
30951709Smlf /*
30961709Smlf * Sun branded drives are shipped write cache disabled. The default is to
30971709Smlf * force write write caching on.
30981709Smlf */
30991709Smlf static void
ata_set_write_cache(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp)31001709Smlf ata_set_write_cache(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp)
31011709Smlf {
31021709Smlf char *path;
31031709Smlf
3104*8686SXun.Ni@Sun.COM if (!(IS_WRITE_CACHE_SUPPORTED(ata_drvp->ad_id)))
3105*8686SXun.Ni@Sun.COM return;
3106*8686SXun.Ni@Sun.COM
31071709Smlf if (ata_write_cache == 1) {
31081709Smlf if (ata_set_feature(ata_ctlp, ata_drvp, FC_WRITE_CACHE_ON, 0)
31091709Smlf == FALSE) {
31101709Smlf path = kmem_alloc(MAXPATHLEN + 1, KM_NOSLEEP);
31111709Smlf if (path != NULL) {
31121709Smlf cmn_err(CE_WARN,
31131709Smlf "%s unable to enable write cache targ=%d",
31141709Smlf ddi_pathname(ata_ctlp->ac_dip, path),
31151709Smlf ata_drvp->ad_targ);
31161709Smlf kmem_free(path, MAXPATHLEN + 1);
31171709Smlf }
31181709Smlf }
31191709Smlf } else if (ata_write_cache == -1) {
31201709Smlf if (ata_set_feature(ata_ctlp, ata_drvp, FC_WRITE_CACHE_OFF, 0)
31211709Smlf == FALSE) {
31221709Smlf path = kmem_alloc(MAXPATHLEN + 1, KM_NOSLEEP);
31231709Smlf if (path != NULL) {
31241709Smlf cmn_err(CE_WARN,
31251709Smlf "%s unable to disable write cache targ=%d",
31261709Smlf ddi_pathname(ata_ctlp->ac_dip, path),
31271709Smlf ata_drvp->ad_targ);
31281709Smlf kmem_free(path, MAXPATHLEN + 1);
31291709Smlf }
31301709Smlf }
31311709Smlf }
31321709Smlf }
31333652Syt160523
31343652Syt160523 /*
31353652Syt160523 * Call set feature to spin-up the device.
31363652Syt160523 */
31373652Syt160523 static int
ata_disk_set_feature_spinup(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)31383652Syt160523 ata_disk_set_feature_spinup(
31393652Syt160523 ata_ctl_t *ata_ctlp,
31403652Syt160523 ata_drv_t *ata_drvp,
31413652Syt160523 ata_pkt_t *ata_pktp)
31423652Syt160523 {
31433652Syt160523 int rc;
31443652Syt160523
31453652Syt160523 ADBG_TRACE(("ata_disk_set_feature_spinup entered\n"));
31463652Syt160523
31473652Syt160523 rc = ata_set_feature(ata_ctlp, ata_drvp, 0x07, 0);
31483652Syt160523 if (!rc)
31493652Syt160523 ata_pktp->ap_flags |= AP_ERROR;
31503652Syt160523
31513652Syt160523 return (ATA_FSM_RC_FINI);
31523652Syt160523 }
31533652Syt160523
31543652Syt160523 /*
31553652Syt160523 * Update device ata_id content - IDENTIFY DEVICE command.
31563652Syt160523 */
31573652Syt160523 static int
ata_disk_id_update(ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,ata_pkt_t * ata_pktp)31583652Syt160523 ata_disk_id_update(
31593652Syt160523 ata_ctl_t *ata_ctlp,
31603652Syt160523 ata_drv_t *ata_drvp,
31613652Syt160523 ata_pkt_t *ata_pktp)
31623652Syt160523 {
31633652Syt160523 ddi_acc_handle_t io_hdl1 = ata_ctlp->ac_iohandle1;
31643652Syt160523 caddr_t ioaddr1 = ata_ctlp->ac_ioaddr1;
31653652Syt160523 ddi_acc_handle_t io_hdl2 = ata_ctlp->ac_iohandle2;
31663652Syt160523 caddr_t ioaddr2 = ata_ctlp->ac_ioaddr2;
31673652Syt160523 struct ata_id *aidp = &ata_drvp->ad_id;
31683652Syt160523 int rc;
31693652Syt160523
31703652Syt160523 ADBG_TRACE(("ata_disk_id_update entered\n"));
31713652Syt160523
31723652Syt160523 /*
31733652Syt160523 * select the appropriate drive and LUN
31743652Syt160523 */
31753652Syt160523 ddi_put8(io_hdl1, (uchar_t *)ioaddr1 + AT_DRVHD,
31763652Syt160523 ata_drvp->ad_drive_bits);
31774852Smlf ata_nsecwait(400);
31783652Syt160523
31793652Syt160523 /*
31803652Syt160523 * make certain the drive is selected, and wait for not busy
31813652Syt160523 */
31823652Syt160523 if (!ata_wait(io_hdl2, ioaddr2, ATS_DRDY, ATS_BSY, 5 * 1000000)) {
31833652Syt160523 ADBG_ERROR(("ata_disk_id_update: select failed\n"));
31843652Syt160523 ata_pktp->ap_flags |= AP_ERROR;
31853652Syt160523 return (ATA_FSM_RC_FINI);
31863652Syt160523 }
31873652Syt160523
31883652Syt160523 rc = ata_disk_id(io_hdl1, ioaddr1, io_hdl2, ioaddr2, aidp);
31893652Syt160523
31903652Syt160523 if (!rc) {
31913652Syt160523 ata_pktp->ap_flags |= AP_ERROR;
31923652Syt160523 } else {
31933652Syt160523 swab(aidp->ai_drvser, aidp->ai_drvser,
31943652Syt160523 sizeof (aidp->ai_drvser));
31953652Syt160523 swab(aidp->ai_fw, aidp->ai_fw,
31963652Syt160523 sizeof (aidp->ai_fw));
31973652Syt160523 swab(aidp->ai_model, aidp->ai_model,
31983652Syt160523 sizeof (aidp->ai_model));
31993652Syt160523 }
32003652Syt160523
32013652Syt160523 return (ATA_FSM_RC_FINI);
32023652Syt160523 }
32033652Syt160523
32043652Syt160523 /*
32053652Syt160523 * Update device firmware.
32063652Syt160523 */
32073652Syt160523 static int
ata_disk_update_fw(gtgt_t * gtgtp,ata_ctl_t * ata_ctlp,ata_drv_t * ata_drvp,caddr_t fwfile,uint_t size,uint8_t type,int flag)32083652Syt160523 ata_disk_update_fw(gtgt_t *gtgtp, ata_ctl_t *ata_ctlp,
32093652Syt160523 ata_drv_t *ata_drvp, caddr_t fwfile,
32103652Syt160523 uint_t size, uint8_t type, int flag)
32113652Syt160523 {
32123652Syt160523 ata_pkt_t *ata_pktp;
32133652Syt160523 gcmd_t *gcmdp = NULL;
32143652Syt160523 caddr_t fwfile_memp = NULL, tmp_fwfile_memp;
32153652Syt160523 uint_t total_sec_count, sec_count, start_sec = 0;
32163652Syt160523 uint8_t cmd_type;
32173652Syt160523 int rc;
32183652Syt160523
32193652Syt160523 /*
32203652Syt160523 * First check whether DOWNLOAD MICROCODE command is supported
32213652Syt160523 */
32223652Syt160523 if (!(ata_drvp->ad_id.ai_cmdset83 & 0x1)) {
32233652Syt160523 ADBG_ERROR(("drive doesn't support download "
32243652Syt160523 "microcode command\n"));
32253652Syt160523 return (ENOTSUP);
32263652Syt160523 }
32273652Syt160523
32283652Syt160523 switch (type) {
32293652Syt160523 case FW_TYPE_TEMP:
32303652Syt160523 cmd_type = ATCM_FW_TEMP;
32313652Syt160523 break;
32323652Syt160523
32333652Syt160523 case FW_TYPE_PERM:
32343652Syt160523 cmd_type = ATCM_FW_PERM;
32353652Syt160523 break;
32363652Syt160523
32373652Syt160523 default:
32383652Syt160523 return (EINVAL);
32393652Syt160523 }
32403652Syt160523
32413652Syt160523 /* Temporary subcommand is obsolete in ATA/ATAPI-8 version */
32423652Syt160523 if (cmd_type == ATCM_FW_TEMP) {
32433652Syt160523 if (ata_drvp->ad_id.ai_majorversion & ATAC_MAJVER_8) {
32443652Syt160523 ADBG_ERROR(("Temporary use is obsolete in "
32453652Syt160523 "ATA/ATAPI-8 version\n"));
32463652Syt160523 return (ENOTSUP);
32473652Syt160523 }
32483652Syt160523 }
32493652Syt160523
32503652Syt160523 total_sec_count = size >> SCTRSHFT;
32513652Syt160523 if (total_sec_count > MAX_FWFILE_SIZE_ONECMD) {
32523652Syt160523 if (cmd_type == ATCM_FW_TEMP) {
32533652Syt160523 ADBG_ERROR(("firmware size: %x sectors is too large\n",
32543652Syt160523 total_sec_count));
32553652Syt160523 return (EINVAL);
32563652Syt160523 } else {
32573652Syt160523 ADBG_WARN(("firmware size: %x sectors is larger than"
32583652Syt160523 " one command, need to use the multicommand"
32593652Syt160523 " subcommand\n", total_sec_count));
32603652Syt160523
32613652Syt160523 cmd_type = ATCM_FW_MULTICMD;
32623652Syt160523 if (!(ata_drvp->ad_id.ai_padding2[15] & 0x10)) {
32633652Syt160523 ADBG_ERROR(("This drive doesn't support "
32643652Syt160523 "the multicommand subcommand\n"));
32653652Syt160523 return (ENOTSUP);
32663652Syt160523 }
32673652Syt160523 }
32683652Syt160523 }
32693652Syt160523
32703652Syt160523 fwfile_memp = kmem_zalloc(size, KM_SLEEP);
32713652Syt160523
32723652Syt160523 if (ddi_copyin(fwfile, fwfile_memp, size, flag)) {
32733652Syt160523 ADBG_ERROR(("ata_disk_update_fw copyin failed\n"));
32743652Syt160523 rc = EFAULT;
32753652Syt160523 goto done;
32763652Syt160523 }
32773652Syt160523
32783652Syt160523 tmp_fwfile_memp = fwfile_memp;
32793652Syt160523
32803652Syt160523 for (; total_sec_count > 0; ) {
32813652Syt160523 if ((gcmdp == NULL) && !(gcmdp =
32823652Syt160523 ghd_gcmd_alloc(gtgtp, sizeof (*ata_pktp), TRUE))) {
32833652Syt160523 ADBG_ERROR(("ata_disk_update_fw alloc failed\n"));
32843652Syt160523 rc = ENOMEM;
32853652Syt160523 goto done;
32863652Syt160523 }
32873652Syt160523
32883652Syt160523 /* set the back ptr from the ata_pkt to the gcmd_t */
32893652Syt160523 ata_pktp = GCMD2APKT(gcmdp);
32903652Syt160523 ata_pktp->ap_gcmdp = gcmdp;
32913652Syt160523 ata_pktp->ap_hd = ata_drvp->ad_drive_bits;
32923652Syt160523 ata_pktp->ap_bytes_per_block = ata_drvp->ad_bytes_per_block;
32933652Syt160523
32943652Syt160523 /* use PIO mode to update disk firmware */
32953652Syt160523 ata_pktp->ap_start = ata_disk_start_pio_out;
32963652Syt160523 ata_pktp->ap_intr = ata_disk_intr_pio_out;
32973652Syt160523 ata_pktp->ap_complete = NULL;
32983652Syt160523
32993652Syt160523 ata_pktp->ap_cmd = ATC_LOAD_FW;
33003652Syt160523 /* use ap_bcount to set subcommand code */
33013652Syt160523 ata_pktp->ap_bcount = (size_t)cmd_type;
33023652Syt160523 ata_pktp->ap_pciide_dma = FALSE;
33033652Syt160523 ata_pktp->ap_sg_cnt = 0;
33043652Syt160523
33053652Syt160523 sec_count = min(total_sec_count, MAX_FWFILE_SIZE_ONECMD);
33063652Syt160523 ata_pktp->ap_flags = 0;
33073652Syt160523
33087671SZhongyan.Gu@Sun.COM ata_pktp->ap_count = (ushort_t)sec_count;
33093652Syt160523 ata_pktp->ap_startsec = start_sec;
33103652Syt160523 ata_pktp->ap_v_addr = tmp_fwfile_memp;
33113652Syt160523 ata_pktp->ap_resid = sec_count << SCTRSHFT;
33123652Syt160523
33133652Syt160523 /* add it to the queue, and use POLL mode */
33143652Syt160523 rc = ghd_transport(&ata_ctlp->ac_ccc, gcmdp, gcmdp->cmd_gtgtp,
33153652Syt160523 ata_disk_updatefw_time, TRUE, NULL);
33163652Syt160523
33173652Syt160523 if (rc != TRAN_ACCEPT) {
33183652Syt160523 /* this should never, ever happen */
33193652Syt160523 rc = ENOTSUP;
33203652Syt160523 goto done;
33213652Syt160523 }
33223652Syt160523
33233652Syt160523 if (ata_pktp->ap_flags & AP_ERROR) {
33243652Syt160523 if (ata_pktp->ap_error & ATE_ABORT) {
33253652Syt160523 rc = ENOTSUP;
33263652Syt160523 } else
33273652Syt160523 rc = EIO;
33283652Syt160523 goto done;
33293652Syt160523
33303652Syt160523 } else {
33313652Syt160523 total_sec_count -= sec_count;
33323652Syt160523 tmp_fwfile_memp += sec_count << SCTRSHFT;
33333652Syt160523 start_sec += sec_count;
33343652Syt160523 }
33353652Syt160523 }
33363652Syt160523
33373652Syt160523 rc = 0;
33383652Syt160523 done:
33393652Syt160523 if (gcmdp != NULL)
33403652Syt160523 ghd_gcmd_free(gcmdp);
33413652Syt160523
33423652Syt160523 kmem_free(fwfile_memp, size);
33433652Syt160523
33443652Syt160523 return (rc);
33453652Syt160523 }
3346