xref: /onnv-gate/usr/src/uts/intel/io/dktp/controller/ata/ata_disk.c (revision 8686:7520898c2919)
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, &GTGTP2ATAP(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(&GTGTP2ATAP(gtgtp)->ac_ccc, gcmdp, bp, flags,
14201709Smlf 			callback, arg, &GTGTP2ATATGTP(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(&GTGTP2ATAP(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