diff options
Diffstat (limited to 'usr/src/uts/intel')
| -rw-r--r-- | usr/src/uts/intel/Makefile.files | 3 | ||||
| -rw-r--r-- | usr/src/uts/intel/Makefile.intel.shared | 1 | ||||
| -rw-r--r-- | usr/src/uts/intel/ia32/ml/modstubs.s | 2 | ||||
| -rw-r--r-- | usr/src/uts/intel/io/acpica/acpica.c | 211 | ||||
| -rw-r--r-- | usr/src/uts/intel/io/agpgart/amd64_gart.c | 24 | ||||
| -rw-r--r-- | usr/src/uts/intel/io/dktp/controller/ata/ata_cmd.h | 5 | ||||
| -rw-r--r-- | usr/src/uts/intel/io/dktp/controller/ata/ata_common.c | 632 | ||||
| -rw-r--r-- | usr/src/uts/intel/io/dktp/controller/ata/ata_common.h | 15 | ||||
| -rw-r--r-- | usr/src/uts/intel/io/dktp/dcdev/dadk.c | 162 | ||||
| -rw-r--r-- | usr/src/uts/intel/io/dktp/disk/cmdk.c | 225 | ||||
| -rw-r--r-- | usr/src/uts/intel/io/dktp/hba/ghd/ghd_debug.c | 21 | ||||
| -rw-r--r-- | usr/src/uts/intel/io/pci/pci_pci.c | 56 | ||||
| -rw-r--r-- | usr/src/uts/intel/io/vgatext/vgatext.c | 219 | ||||
| -rw-r--r-- | usr/src/uts/intel/os/cpr_intel.c | 75 | ||||
| -rw-r--r-- | usr/src/uts/intel/os/name_to_major | 2 | ||||
| -rw-r--r-- | usr/src/uts/intel/promif/prom_env.c | 23 | ||||
| -rwxr-xr-x | usr/src/uts/intel/srn/Makefile | 84 | ||||
| -rw-r--r-- | usr/src/uts/intel/sys/acpica.h | 2 | ||||
| -rw-r--r-- | usr/src/uts/intel/sys/promif.h | 10 | 
19 files changed, 1433 insertions, 339 deletions
| diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files index c84c1608c3..e4b136dd18 100644 --- a/usr/src/uts/intel/Makefile.files +++ b/usr/src/uts/intel/Makefile.files @@ -274,3 +274,6 @@ BOOTDEV_OBJS +=		\  	bootdev.o  INC_PATH	+= -I$(UTSBASE)/intel + + +CPR_INTEL_OBJS +=	cpr_intel.o diff --git a/usr/src/uts/intel/Makefile.intel.shared b/usr/src/uts/intel/Makefile.intel.shared index 53267390d6..4602092e15 100644 --- a/usr/src/uts/intel/Makefile.intel.shared +++ b/usr/src/uts/intel/Makefile.intel.shared @@ -208,6 +208,7 @@ DRV_KMODS	+= ahci  DRV_KMODS	+= amd64_gart  DRV_KMODS	+= amr  DRV_KMODS	+= agpgart +DRV_KMODS	+= srn  DRV_KMODS	+= agptarget  DRV_KMODS	+= arp  DRV_KMODS	+= asy diff --git a/usr/src/uts/intel/ia32/ml/modstubs.s b/usr/src/uts/intel/ia32/ml/modstubs.s index d6d1bc3d58..d6f06c6e1f 100644 --- a/usr/src/uts/intel/ia32/ml/modstubs.s +++ b/usr/src/uts/intel/ia32/ml/modstubs.s @@ -596,6 +596,8 @@ fcnname/**/_info:							\  	NO_UNLOAD_STUB(klmmod, lm_svc,		nomod_zero);  	NO_UNLOAD_STUB(klmmod, lm_shutdown,	nomod_zero);  	NO_UNLOAD_STUB(klmmod, lm_unexport,	nomod_zero); +	NO_UNLOAD_STUB(klmmod, lm_cprresume,	nomod_zero); +	NO_UNLOAD_STUB(klmmod, lm_cprsuspend,	nomod_zero);   	NO_UNLOAD_STUB(klmmod, lm_safelock, nomod_zero);  	NO_UNLOAD_STUB(klmmod, lm_safemap, nomod_zero);  	NO_UNLOAD_STUB(klmmod, lm_has_sleep, nomod_zero); diff --git a/usr/src/uts/intel/io/acpica/acpica.c b/usr/src/uts/intel/io/acpica/acpica.c index b743d46504..98044e8e3d 100644 --- a/usr/src/uts/intel/io/acpica/acpica.c +++ b/usr/src/uts/intel/io/acpica/acpica.c @@ -38,6 +38,7 @@  #include <sys/ddi.h>  #include <sys/sunddi.h>  #include <sys/esunddi.h> +#include <sys/kstat.h>  #include <sys/acpi/acpi.h>  #include <sys/acpica.h> @@ -57,10 +58,17 @@ static	struct modlinkage modlinkage = {  };  /* + * Local prototypes + */ + +static void	acpica_init_kstats(void); + +/*   * Local data   */  static kmutex_t	acpica_module_lock; +static kstat_t	*acpica_ksp;  /*   * State of acpica subsystem @@ -99,17 +107,23 @@ int acpica_muzzle_debug_output = 0;  int acpica_muzzle_debug_output = 1;  #endif +/* + * ACPI DDI hooks + */ +static int acpica_ddi_setwake(dev_info_t *dip, int level);  int  _init(void)  {  	int error = EBUSY;  	int	status; +	extern int (*acpi_fp_setwake)();  	mutex_init(&acpica_module_lock, NULL, MUTEX_DRIVER, NULL);  	if ((error = mod_install(&modlinkage)) != 0) {  		mutex_destroy(&acpica_module_lock); +		goto load_error;  	}  	AcpiGbl_EnableInterpreterSlack = (acpica_enable_interpreter_slack != 0); @@ -118,6 +132,9 @@ _init(void)  		cmn_err(CE_WARN, "!acpica: error pre-init:1:%d", status);  	} +	acpi_fp_setwake = acpica_ddi_setwake; + +load_error:  	return (error);  } @@ -388,6 +405,7 @@ acpica_init()  		acpica_ec_init();  		acpica_init_state = ACPICA_INITIALIZED; +		acpica_init_kstats();  error:  		if (acpica_init_state != ACPICA_INITIALIZED) {  			cmn_err(CE_NOTE, "!failed to initialize" @@ -487,3 +505,196 @@ acpica_get_sci(int *sci_irq, iflag_t *sci_flags)  	return (AE_OK);  } + +/* + * Sets ACPI wake state for device referenced by dip. + * If level is S0 (0), disables wake event; otherwise, + * enables wake event which will wake system from level. + */ +static int +acpica_ddi_setwake(dev_info_t *dip, int level) +{ +	ACPI_STATUS	status; +	ACPI_HANDLE	devobj, gpeobj; +	ACPI_OBJECT	*prw, *gpe; +	ACPI_BUFFER	prw_buf; +	int		gpebit, pwr_res_count, prw_level, rv; + +	/* +	 * initialize these early so we can use a common +	 * exit point below +	 */ +	prw_buf.Pointer = NULL; +	prw_buf.Length = ACPI_ALLOCATE_BUFFER; +	rv = 0; + +	/* +	 * Attempt to get a handle to a corresponding ACPI object. +	 * If no object is found, return quietly, since not all +	 * devices have corresponding ACPI objects. +	 */ +	status = acpica_get_handle(dip, &devobj); +	if (ACPI_FAILURE(status)) { +		char pathbuf[MAXPATHLEN]; +		ddi_pathname(dip, pathbuf); +#ifdef DEBUG +		cmn_err(CE_NOTE, "!acpica_ddi_setwake: could not get" +		    " handle for %s, %s:%d", pathbuf, ddi_driver_name(dip), +		    ddi_get_instance(dip)); +#endif +		goto done; +	} + +	/* +	 * Attempt to evaluate _PRW object. +	 * If no valid object is found, return quietly, since not all +	 * devices have _PRW objects. +	 */ +	status = AcpiEvaluateObject(devobj, "_PRW", NULL, &prw_buf); +	prw = prw_buf.Pointer; +	if (ACPI_FAILURE(status) || prw == NULL || +	    prw->Type != ACPI_TYPE_PACKAGE || prw->Package.Count < 2 || +	    prw->Package.Elements[1].Type != ACPI_TYPE_INTEGER) { +		cmn_err(CE_NOTE, "acpica_ddi_setwake: could not " +		    " evaluate _PRW"); +		goto done; +	} + +	/* fetch the lowest wake level from the _PRW */ +	prw_level = prw->Package.Elements[1].Integer.Value; + +	/* +	 * process the GPE description +	 */ +	switch (prw->Package.Elements[0].Type) { +	case ACPI_TYPE_INTEGER: +		gpeobj = NULL; +		gpebit = prw->Package.Elements[0].Integer.Value; +		break; +	case ACPI_TYPE_PACKAGE: +		gpe = &prw->Package.Elements[0]; +		if (gpe->Package.Count != 2 || +		    gpe->Package.Elements[1].Type != ACPI_TYPE_INTEGER) +			goto done; +		gpeobj = gpe->Package.Elements[0].Reference.Handle; +		gpebit = gpe->Package.Elements[1].Integer.Value; +		if (gpeobj == NULL) +			goto done; +	default: +		goto done; +	} + +	rv = -1; +	if (level == 0) { +		if (ACPI_FAILURE(AcpiDisableGpe(gpeobj, gpebit, ACPI_NOT_ISR))) +			goto done; +	} else if (prw_level <= level) { +		if (ACPI_SUCCESS( +		    AcpiSetGpeType(gpeobj, gpebit, ACPI_GPE_TYPE_WAKE))) +			if (ACPI_FAILURE( +			    AcpiEnableGpe(gpeobj, gpebit, ACPI_NOT_ISR))) +				goto done; +	} +	rv = 0; +done: +	if (prw_buf.Pointer != NULL) +		AcpiOsFree(prw_buf.Pointer); +	return (rv); +} + +/* + * kstat access to a limited set of ACPI propertis + */ +static void +acpica_init_kstats() +{ +	ACPI_HANDLE	s3handle; +	ACPI_STATUS	status; +	FADT_DESCRIPTOR	*fadt; +	kstat_named_t *knp; + +	/* +	 * Create a small set of named kstats; just return in the rare +	 * case of a failure, * in which case, the kstats won't be present. +	 */ +	if ((acpica_ksp = kstat_create("acpi", 0, "acpi", "misc", +	    KSTAT_TYPE_NAMED, 2, 0)) == NULL) +		return; + +	/* +	 * initialize kstat 'S3' to reflect the presence of \_S3 in +	 * the ACPI namespace (1 = present, 0 = not present) +	 */ +	knp = acpica_ksp->ks_data; +	knp->value.l = (AcpiGetHandle(NULL, "\\_S3", &s3handle) == AE_OK); +	kstat_named_init(knp, "S3", KSTAT_DATA_LONG); +	knp++;		/* advance to next named kstat */ + +	/* +	 * initialize kstat 'preferred_pm_profile' to the value +	 * contained in the (always present) FADT +	 */ +	status = AcpiGetFirmwareTable(FADT_SIG, 1, ACPI_LOGICAL_ADDRESSING, +	    (ACPI_TABLE_HEADER **)&fadt); +	knp->value.l = (status == AE_OK) ? fadt->Prefer_PM_Profile : -1; +	kstat_named_init(knp, "preferred_pm_profile", KSTAT_DATA_LONG); + +	/* +	 * install the named kstats +	 */ +	kstat_install(acpica_ksp); +} + +/* + * Attempt to save the current ACPI settings (_CRS) for the device + * which corresponds to the supplied devinfo node.  The settings are + * saved as a property on the dip.  If no ACPI object is found to be + * associated with the devinfo node, no action is taken and no error + * is reported. + */ +void +acpica_ddi_save_resources(dev_info_t *dip) +{ +	ACPI_HANDLE	devobj; +	ACPI_BUFFER	resbuf; +	int		ret; + +	resbuf.Length = ACPI_ALLOCATE_BUFFER; +	if (ACPI_FAILURE(acpica_get_handle(dip, &devobj)) || +	    ACPI_FAILURE(AcpiGetCurrentResources(devobj, &resbuf))) +		return; + +	ret = ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP, +	    "acpi-crs", resbuf.Pointer, resbuf.Length); + +	ASSERT(ret == DDI_PROP_SUCCESS); + +	AcpiOsFree(resbuf.Pointer); +} + +/* + * If the supplied devinfo node has an ACPI settings property attached, + * restore them to the associated ACPI device using _SRS.  The property + * is deleted from the devinfo node afterward. + */ +void +acpica_ddi_restore_resources(dev_info_t *dip) +{ +	ACPI_HANDLE	devobj; +	ACPI_BUFFER	resbuf; +	uchar_t		*propdata; +	uint_t		proplen; + +	if (ACPI_FAILURE(acpica_get_handle(dip, &devobj))) +		return; + +	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, +	    "acpi-crs", &propdata, &proplen) != DDI_PROP_SUCCESS) +		return; + +	resbuf.Pointer = propdata; +	resbuf.Length = proplen; +	(void) AcpiSetCurrentResources(devobj, &resbuf); +	ddi_prop_free(propdata); +	(void) ddi_prop_remove(DDI_DEV_T_ANY, dip, "acpi-crs"); +} diff --git a/usr/src/uts/intel/io/agpgart/amd64_gart.c b/usr/src/uts/intel/io/agpgart/amd64_gart.c index fbcebf781d..22d6ef3994 100644 --- a/usr/src/uts/intel/io/agpgart/amd64_gart.c +++ b/usr/src/uts/intel/io/agpgart/amd64_gart.c @@ -1,5 +1,5 @@  /* - * Copyright 2005 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -173,9 +173,18 @@ amd64_gart_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)  	int			status;  	char			buf[80]; -	if (cmd != DDI_ATTACH) +	switch (cmd) { +	default:  		return (DDI_FAILURE); +	case DDI_RESUME: +		/* Nothing special is needed for resume. */ +		return (DDI_SUCCESS); + +	case DDI_ATTACH: +		break; +	} +  	instance = ddi_get_instance(dip);  	if (ddi_soft_state_zalloc(amd64_gart_glob_soft_handle, instance) != @@ -209,9 +218,18 @@ amd64_gart_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)  	amd64_gart_softstate_t	*sc;  	char			buf[80]; -	if (cmd != DDI_DETACH) +	switch (cmd) { +	default:  		return (DDI_FAILURE); +	case DDI_SUSPEND: +		/* Nothing special is needed for suspend */ +		return (DDI_SUCCESS); + +	case DDI_DETACH: +		break; +	} +  	instance = ddi_get_instance(dip);  	sc = ddi_get_soft_state(amd64_gart_glob_soft_handle, instance); diff --git a/usr/src/uts/intel/io/dktp/controller/ata/ata_cmd.h b/usr/src/uts/intel/io/dktp/controller/ata/ata_cmd.h index 9483f1e9b0..3607ff1cda 100644 --- a/usr/src/uts/intel/io/dktp/controller/ata/ata_cmd.h +++ b/usr/src/uts/intel/io/dktp/controller/ata/ata_cmd.h @@ -2,7 +2,7 @@   * CDDL HEADER START   *   * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License").   + * Common Development and Distribution License (the "License").   * You may not use this file except in compliance with the License.   *   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE @@ -20,7 +20,7 @@   */  /* - * Copyright 1996 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -45,6 +45,7 @@ extern "C" {  #define	ATC_DOOR_LOCK	0xde	/* door lock				*/  #define	ATC_DOOR_UNLOCK	0xdf	/* door unlock				*/  #define	ATC_IDLE	0xe3	/* idle					*/ +#define	ATC_SLEEP	0xe6	/* sleep				*/  /*   * ATA/ATAPI-4 disk commands. diff --git a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c index 17294569fb..7fb8da9ff0 100644 --- a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c +++ b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c @@ -99,6 +99,12 @@ static	int	ata_check_revert_to_defaults(ata_drv_t *ata_drvp);  static  void	ata_show_transfer_mode(ata_ctl_t *, ata_drv_t *);  static	int	ata_spec_init_controller(dev_info_t *dip); +static void	ata_init_pm(dev_info_t *); +static int	ata_suspend(dev_info_t *); +static int	ata_resume(dev_info_t *); +static int	ata_power(dev_info_t *, int, int); +static int	ata_change_power(dev_info_t *, uint8_t); +static int	ata_is_pci(dev_info_t *);  /*   * Local static data @@ -114,6 +120,21 @@ int	ata_reset_bus_watchdog = 1000;  /* + * Use local or framework power management + */ + +#ifdef	ATA_USE_AUTOPM +#define	ATA_BUSY_COMPONENT(d, c)	((void)pm_busy_component(d, c)) +#define	ATA_IDLE_COMPONENT(d, c)	((void)pm_idle_component(d, c)) +#define	ATA_RAISE_POWER(d, c, l)	pm_raise_power(d, c, l) +#define	ATA_LOWER_POWER(d, c, l)	pm_lower_power(d, c, l) +#else +#define	ATA_BUSY_COMPONENT(d, c) +#define	ATA_IDLE_COMPONENT(d, c) +#define	ATA_RAISE_POWER(d, c, l)	ata_power(d, c, l) +#define	ATA_LOWER_POWER(d, c, l)	ata_power(d, c, l) +#endif +/*   * number of seconds to wait during various operations   */  int	ata_flush_delay = 5 * 1000000; @@ -228,7 +249,8 @@ ata_devo_reset(  		if ((ata_drvp->ad_flags & AD_DISK) != 0 &&  		    ((ata_drvp->ad_flags & AD_NORVRT) == 0)) {  			/* Enable revert to defaults when reset */ -			(void) ata_set_feature(ata_ctlp, ata_drvp, 0xCC, 0); +			(void) ata_set_feature(ata_ctlp, ata_drvp, +			    ATSF_ENA_REVPOD, 0);  		}  		/* @@ -245,7 +267,7 @@ ata_devo_reset(  			 */  			rc = ata_flush_cache(ata_ctlp, ata_drvp);  			ADBG_WARN(("ata_flush_cache %s\n", -				rc ? "okay" : "failed")); +			    rc ? "okay" : "failed"));  			if (!rc)  				flush_okay = FALSE; @@ -297,7 +319,8 @@ static struct dev_ops	ata_ops = {  	ata_detach,		/* detach */  	ata_devo_reset,		/* reset */  	&ata_cb_ops,		/* driver operations */ -	NULL			/* bus operations */ +	NULL,			/* bus operations */ +	ata_power		/* power */  };  /* driver loadable module wrapper */ @@ -419,8 +442,14 @@ ata_attach(  		debug_enter("\nATA_ATTACH\n\n");  #endif -	if (cmd != DDI_ATTACH) +	switch (cmd) { +	case DDI_ATTACH: +		break; +	case DDI_RESUME: +		return (ata_resume(dip)); +	default:  		return (DDI_FAILURE); +	}  	/* initialize controller */  	ata_ctlp = ata_init_controller(dip); @@ -476,14 +505,14 @@ ata_attach(  	 * confused by non-existent drives.  	 */  	ddi_put8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_drvhd, -		first_drvp->ad_drive_bits); +	    first_drvp->ad_drive_bits);  	ata_nsecwait(400);  	/*  	 * make certain the drive selected  	 */  	if (!ata_wait(ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, -			0, ATS_BSY, 5000000)) { +	    0, ATS_BSY, 5000000)) {  		ADBG_ERROR(("ata_attach: select failed\n"));  	} @@ -525,6 +554,8 @@ ata_attach(  	ata_ctlp->ac_flags |= AC_ATTACHED;  	mutex_exit(&ata_ctlp->ac_ccc.ccc_hba_mutex); +	ata_init_pm(dip); +  	ddi_report_dev(dip);  	return (DDI_SUCCESS); @@ -550,8 +581,14 @@ ata_detach(  	ADBG_TRACE(("ata_detach entered\n")); -	if (cmd != DDI_DETACH) +	switch (cmd) { +	case DDI_DETACH: +		break; +	case DDI_SUSPEND: +		return (ata_suspend(dip)); +	default:  		return (DDI_FAILURE); +	}  	instance = ddi_get_instance(dip);  	ata_ctlp = ddi_get_soft_state(ata_state, instance); @@ -559,6 +596,17 @@ ata_detach(  	if (!ata_ctlp)  		return (DDI_SUCCESS); +	if (ata_ctlp->ac_pm_support) { +		ATA_BUSY_COMPONENT(dip, 0); +		if (ata_ctlp->ac_pm_level != PM_LEVEL_D0) { +			if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) != +			    DDI_SUCCESS) { +				ATA_IDLE_COMPONENT(dip, 0); +				return (DDI_FAILURE); +			} +		} +		(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components"); +	}  	ata_ctlp->ac_flags &= ~AC_ATTACHED;  	/* destroy ata module */ @@ -641,8 +689,8 @@ ata_bus_ctl(  		/* These ops shouldn't be called by a target driver */  		ADBG_ERROR(("ata_bus_ctl: %s%d: invalid op (%d) from %s%d\n", -			ddi_driver_name(d), ddi_get_instance(d), o, -			ddi_driver_name(r), ddi_get_instance(r))); +		    ddi_driver_name(d), ddi_get_instance(d), o, +		    ddi_driver_name(r), ddi_get_instance(r)));  		return (DDI_FAILURE); @@ -683,7 +731,7 @@ ata_bus_ctl(  			target_type = ATA_DEV_ATAPI;  		else {  			ADBG_WARN(("ata_bus_ctl: invalid target class %s\n", -				bufp)); +			    bufp));  			ddi_prop_free(bufp);  			return (DDI_FAILURE);  		} @@ -710,17 +758,17 @@ ata_bus_ctl(  		/* get (target,lun) of child device */  		targ = ddi_prop_get_int(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS, -					"target", -1); +		    "target", -1);  		if (targ == -1) {  			ADBG_WARN(("ata_bus_ctl: failed to get targ num\n"));  			return (DDI_FAILURE);  		}  		lun = ddi_prop_get_int(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS, -			"lun", 0); +		    "lun", 0);  		if ((targ < 0) || (targ >= ATA_MAXTARG) || -				(lun < 0) || (lun >= ATA_MAXLUN)) { +		    (lun < 0) || (lun >= ATA_MAXLUN)) {  			return (DDI_FAILURE);  		} @@ -743,7 +791,7 @@ ata_bus_ctl(  		if (strcmp(ddi_get_name(tdip), "cmdk") == 0) {  			if ((target_type == ATA_DEV_DISK) && -				(target_type != drive_type)) +			    (target_type != drive_type))  				return (DDI_FAILURE);  			target_type = drive_type; @@ -757,9 +805,9 @@ ata_bus_ctl(  				if (ndi_prop_update_string(DDI_DEV_T_NONE, tdip,  				    "disk", disk_prop) != DDI_PROP_SUCCESS) {  					ADBG_WARN(("ata_bus_ctl: failed to " -						"create disk prop\n")); +					    "create disk prop\n"));  					return (DDI_FAILURE); -				    } +				}  			}  			if (ndi_prop_update_string(DDI_DEV_T_NONE, tdip, @@ -820,7 +868,7 @@ ata_hba_complete(  	ata_pktp = GCMD2APKT(gcmdp);  	if (ata_pktp->ap_complete)  		(*ata_pktp->ap_complete)(ata_drvp, ata_pktp, -			do_callback); +		    do_callback);  }  /* GHD ccc_timeout_func callback */ @@ -919,7 +967,7 @@ ata_init_controller(  	if (ata_ctlp == NULL) {  		ADBG_WARN(("ata_init_controller: failed to find " -				"controller struct\n")); +		    "controller struct\n"));  		return (NULL);  	} @@ -933,14 +981,14 @@ ata_init_controller(  	 * map the device registers  	 */  	if (!ata_setup_ioaddr(dip, &ata_ctlp->ac_iohandle1, &ioaddr1, -			&ata_ctlp->ac_iohandle2, &ioaddr2, -			&ata_ctlp->ac_bmhandle, &ata_ctlp->ac_bmaddr)) { +	    &ata_ctlp->ac_iohandle2, &ioaddr2, +	    &ata_ctlp->ac_bmhandle, &ata_ctlp->ac_bmaddr)) {  		(void) ata_detach(dip, DDI_DETACH);  		return (NULL);  	}  	ADBG_INIT(("ata_init_controller: ioaddr1 = 0x%p, ioaddr2 = 0x%p\n", -			ioaddr1, ioaddr2)); +	    ioaddr1, ioaddr2));  	/*  	 * Do ARQ setup @@ -980,12 +1028,12 @@ ata_init_controller(  	 * drop after a resume.  	 */  	ata_ctlp->ac_timing_flags = ddi_prop_get_int(DDI_DEV_T_ANY, -			dip, DDI_PROP_DONTPASS, "timing_flags", 0); +	    dip, DDI_PROP_DONTPASS, "timing_flags", 0);  	/*  	 * get max transfer size, default to 256 sectors  	 */  	ata_ctlp->ac_max_transfer = ddi_prop_get_int(DDI_DEV_T_ANY, -			dip, DDI_PROP_DONTPASS, "max_transfer", 0x100); +	    dip, DDI_PROP_DONTPASS, "max_transfer", 0x100);  	if (ata_ctlp->ac_max_transfer < 1)  		ata_ctlp->ac_max_transfer = 1;  	if (ata_ctlp->ac_max_transfer > 0x100) @@ -995,7 +1043,7 @@ ata_init_controller(  	 * Get the standby timer value  	 */  	ata_ctlp->ac_standby_time = ddi_prop_get_int(DDI_DEV_T_ANY, -			dip, DDI_PROP_DONTPASS, "standby", -1); +	    dip, DDI_PROP_DONTPASS, "standby", -1);  	/*  	 * If this is a /pci/pci-ide instance check to see if @@ -1011,9 +1059,9 @@ ata_init_controller(  			return (NULL);  		}  		(void) sprintf(prop_buf, "SUNW-ata-%04x-isa", -			addr1); +		    addr1);  		if (ddi_prop_exists(DDI_DEV_T_ANY, ddi_root_node(), -				    DDI_PROP_DONTPASS, prop_buf)) { +		    DDI_PROP_DONTPASS, prop_buf)) {  			(void) ata_detach(dip, DDI_DETACH);  			return (NULL);  		} @@ -1029,11 +1077,11 @@ ata_init_controller(  	GHD_WAITQ_INIT(&ata_ctlp->ac_ccc.ccc_waitq, NULL, 1);  	if (!ghd_register("ata", &ata_ctlp->ac_ccc, dip, 0, ata_ctlp, -			atapi_ccballoc, atapi_ccbfree, -			ata_pciide_dma_sg_func, ata_hba_start, -			ata_hba_complete, ata_intr, -			ata_get_status, ata_process_intr, ata_timeout_func, -			&ata_timer_conf, NULL)) { +	    atapi_ccballoc, atapi_ccbfree, +	    ata_pciide_dma_sg_func, ata_hba_start, +	    ata_hba_complete, ata_intr, +	    ata_get_status, ata_process_intr, ata_timeout_func, +	    &ata_timer_conf, NULL)) {  		(void) ata_detach(dip, DDI_DETACH);  		return (NULL);  	} @@ -1094,7 +1142,7 @@ ata_init_drive(  	int	valid_version = 0;  	ADBG_TRACE(("ata_init_drive entered, targ = %d, lun = %d\n", -		    targ, lun)); +	    targ, lun));  	/* check if device already exists */ @@ -1114,7 +1162,7 @@ ata_init_drive(  	ata_drvp->ad_ctlp = ata_ctlp;  	ata_drvp->ad_targ = targ;  	ata_drvp->ad_drive_bits = -		(ata_drvp->ad_targ == 0 ? ATDH_DRIVE0 : ATDH_DRIVE1); +	    (ata_drvp->ad_targ == 0 ? ATDH_DRIVE0 : ATDH_DRIVE1);  	/*  	 * Add the LUN for SFF-8070i support  	 */ @@ -1127,11 +1175,11 @@ ata_init_drive(  	 */  	drive_type = ata_drive_type(ata_drvp->ad_drive_bits, -				    ata_ctlp->ac_iohandle1, -				    ata_ctlp->ac_ioaddr1, -				    ata_ctlp->ac_iohandle2, -				    ata_ctlp->ac_ioaddr2, -				    aidp); +	    ata_ctlp->ac_iohandle1, +	    ata_ctlp->ac_ioaddr1, +	    ata_ctlp->ac_iohandle2, +	    ata_ctlp->ac_ioaddr2, +	    aidp);  	switch (drive_type) {  	case ATA_DEV_NONE: @@ -1150,11 +1198,11 @@ ata_init_drive(  	 */  	if (!ata_strncmp(nec_260, aidp->ai_model, sizeof (aidp->ai_model))) {  		swab(aidp->ai_drvser, aidp->ai_drvser, -			sizeof (aidp->ai_drvser)); +		    sizeof (aidp->ai_drvser));  		swab(aidp->ai_fw, aidp->ai_fw, -			sizeof (aidp->ai_fw)); +		    sizeof (aidp->ai_fw));  		swab(aidp->ai_model, aidp->ai_model, -			sizeof (aidp->ai_model)); +		    sizeof (aidp->ai_model));  	}  	/* @@ -1177,8 +1225,8 @@ ata_init_drive(  		buf[i] = '\0';  	ATAPRT(("?\t%s device at targ %d, lun %d lastlun 0x%x\n", -		(ATAPIDRV(ata_drvp) ? "ATAPI":"IDE"), -		ata_drvp->ad_targ, ata_drvp->ad_lun, aidp->ai_lastlun)); +	    (ATAPIDRV(ata_drvp) ? "ATAPI":"IDE"), +	    ata_drvp->ad_targ, ata_drvp->ad_lun, aidp->ai_lastlun));  	ATAPRT(("?\tmodel %s\n", buf)); @@ -1191,21 +1239,21 @@ ata_init_drive(  		}  		ATAPRT((  		    "?\tATA/ATAPI-%d supported, majver 0x%x minver 0x%x\n", -			valid_version, -			aidp->ai_majorversion, -			aidp->ai_minorversion)); +		    valid_version, +		    aidp->ai_majorversion, +		    aidp->ai_minorversion));  	}  	if (ata_capability_data) {  		ATAPRT(("?\t\tstat %x, err %x\n", -			ddi_get8(ata_ctlp->ac_iohandle2, -				ata_ctlp->ac_altstatus), -			ddi_get8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_error))); +		    ddi_get8(ata_ctlp->ac_iohandle2, +		    ata_ctlp->ac_altstatus), +		    ddi_get8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_error)));  		ATAPRT(("?\t\tcfg 0x%x, cap 0x%x\n", -			aidp->ai_config, -			aidp->ai_cap)); +		    aidp->ai_config, +		    aidp->ai_cap));  		/*  		 * Be aware that ATA-6 and later drives may not provide valid @@ -1220,34 +1268,34 @@ ata_init_drive(  			 * Supported version less then ATA-6  			 */  			ATAPRT(("?\t\tcyl %d, hd %d, sec/trk %d\n", -				aidp->ai_fixcyls, -				aidp->ai_heads, -				aidp->ai_sectors)); +			    aidp->ai_fixcyls, +			    aidp->ai_heads, +			    aidp->ai_sectors));  		}  		ATAPRT(("?\t\tmult1 0x%x, mult2 0x%x\n", -			aidp->ai_mult1, -			aidp->ai_mult2)); +		    aidp->ai_mult1, +		    aidp->ai_mult2));  		if (valid_version && aidp->ai_majorversion < ATAC_MAJVER_4) {  			ATAPRT((  			"?\t\tpiomode 0x%x, dmamode 0x%x, advpiomode 0x%x\n", -				aidp->ai_piomode, -				aidp->ai_dmamode, -				aidp->ai_advpiomode)); +			    aidp->ai_piomode, +			    aidp->ai_dmamode, +			    aidp->ai_advpiomode));  		} else {  			ATAPRT(("?\t\tadvpiomode 0x%x\n", -				aidp->ai_advpiomode)); +			    aidp->ai_advpiomode));  		}  		ATAPRT(("?\t\tminpio %d, minpioflow %d\n", -			aidp->ai_minpio, -			aidp->ai_minpioflow)); +		    aidp->ai_minpio, +		    aidp->ai_minpioflow));  		if (valid_version && aidp->ai_majorversion >= ATAC_MAJVER_4 &&  		    (aidp->ai_validinfo & ATAC_VALIDINFO_83)) {  			ATAPRT(("?\t\tdwdma 0x%x, ultradma 0x%x\n", -				aidp->ai_dworddma, -				aidp->ai_ultradma)); +			    aidp->ai_dworddma, +			    aidp->ai_ultradma));  		} else {  			ATAPRT(("?\t\tdwdma 0x%x\n", -				aidp->ai_dworddma)); +			    aidp->ai_dworddma));  		}  	} @@ -1268,7 +1316,7 @@ ata_init_drive(  	 * lock the drive's current settings in case I have to  	 * reset the drive due to some sort of error  	 */ -	(void) ata_set_feature(ata_ctlp, ata_drvp, 0x66, 0); +	(void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_DIS_REVPOD, 0);  	return (ata_drvp); @@ -1299,14 +1347,14 @@ ata_uninit_drive(  	 * Select the correct drive  	 */  	ddi_put8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_drvhd, -		ata_drvp->ad_drive_bits); +	    ata_drvp->ad_drive_bits);  	ata_nsecwait(400);  	/*  	 * Disable interrupts from the drive  	 */  	ddi_put8(ata_ctlp->ac_iohandle2, ata_ctlp->ac_devctl, -		(ATDC_D3 | ATDC_NIEN)); +	    (ATDC_D3 | ATDC_NIEN));  #endif  	/* interface specific clean-ups */ @@ -1352,7 +1400,7 @@ ata_drive_type(  	 * make certain the drive is selected, and wait for not busy  	 */  	(void) ata_wait3(io_hdl2, ioaddr2, 0, ATS_BSY, 0x7f, 0, 0x7f, 0, -		5 * 1000000); +	    5 * 1000000);  	status = ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS); @@ -1481,12 +1529,12 @@ ata_wait3(  		 * check for error conditions  		 */  		if ((val & failure_onbits2) == failure_onbits2 && -				(val & failure_offbits2) == 0) { +		    (val & failure_offbits2) == 0) {  			return (FALSE);  		}  		if ((val & failure_onbits3) == failure_onbits3 && -				(val & failure_offbits3) == 0) { +		    (val & failure_offbits3) == 0) {  			return (FALSE);  		} @@ -1564,7 +1612,7 @@ ata_id_common(  	 * make sure we give them enough time to respond.  	 */  	(void) ata_wait3(io_hdl2, ioaddr2, 0, ATS_BSY, -			ATS_ERR, ATS_BSY, 0x7f, 0, 5 * 1000000); +	    ATS_ERR, ATS_BSY, 0x7f, 0, 5 * 1000000);  	/*  	 * read the status byte and clear the pending interrupt @@ -1581,8 +1629,8 @@ ata_id_common(  	if (status & ATS_BSY) {  		ADBG_ERROR(("ata_id_common: BUSY status 0x%x error 0x%x\n", -			ddi_get8(io_hdl2, (uchar_t *)ioaddr2 +AT_ALTSTATUS), -			ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR))); +		    ddi_get8(io_hdl2, (uchar_t *)ioaddr2 +AT_ALTSTATUS), +		    ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR)));  		return (FALSE);  	} @@ -1596,8 +1644,8 @@ ata_id_common(  		 */  		if (!ata_wait(io_hdl2, ioaddr2, ATS_DRQ, ATS_BSY, 1000000)) {  		ADBG_WARN(("ata_id_common: !DRQ status 0x%x error 0x%x\n", -			ddi_get8(io_hdl2, (uchar_t *)ioaddr2 +AT_ALTSTATUS), -			ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR))); +		    ddi_get8(io_hdl2, (uchar_t *)ioaddr2 +AT_ALTSTATUS), +		    ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR)));  		return (FALSE);  		}  	} @@ -1606,7 +1654,7 @@ ata_id_common(  	 * transfer the data  	 */  	ddi_rep_get16(io_hdl1, (ushort_t *)aidp, (ushort_t *)ioaddr1 + AT_DATA, -		NBPSCTR >> 1, DDI_DEV_NO_AUTOINCR); +	    NBPSCTR >> 1, DDI_DEV_NO_AUTOINCR);  	/* wait for the busy bit to settle */  	ata_nsecwait(400); @@ -1624,10 +1672,10 @@ ata_id_common(  	 *  	 */  	if (!ata_wait(io_hdl2, ioaddr2, (uchar_t)(expect_drdy ? ATS_DRDY : 0), -					(ATS_BSY | ATS_DRQ), 1000000)) { +	    (ATS_BSY | ATS_DRQ), 1000000)) {  		ADBG_WARN(("ata_id_common: bad status 0x%x error 0x%x\n", -			ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS), -			ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR))); +		    ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS), +		    ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR)));  		return (FALSE);  	} @@ -1639,8 +1687,8 @@ ata_id_common(  	 */  	if (status & (ATS_DF | ATS_ERR)) {  		ADBG_WARN(("ata_id_common: status 0x%x error 0x%x \n", -			ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS), -			ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR))); +		    ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS), +		    ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR)));  		return (FALSE);  	}  	return (TRUE); @@ -1677,13 +1725,13 @@ ata_command(  	/* make certain the drive selected */  	if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2, -			(uchar_t)(expect_drdy ? ATS_DRDY : 0), -			ATS_BSY, busy_wait)) { +	    (uchar_t)(expect_drdy ? ATS_DRDY : 0), +	    ATS_BSY, busy_wait)) {  		ADBG_ERROR(("ata_command: select failed " -			    "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x  " -			    "S 0x%x H 0x%x CL 0x%x CH 0x%x\n", -			    expect_drdy, cmd, feature, count, -			    sector, head, cyl_low, cyl_hi)); +		    "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x  " +		    "S 0x%x H 0x%x CL 0x%x CH 0x%x\n", +		    expect_drdy, cmd, feature, count, +		    sector, head, cyl_low, cyl_hi));  		return (FALSE);  	} @@ -1706,10 +1754,10 @@ ata_command(  	/* wait for not busy */  	if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY, busy_wait)) {  		ADBG_ERROR(("ata_command: BSY too long!" -			    "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x  " -			    "S 0x%x H 0x%x CL 0x%x CH 0x%x\n", -			    expect_drdy, cmd, feature, count, -			    sector, head, cyl_low, cyl_hi)); +		    "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x  " +		    "S 0x%x H 0x%x CL 0x%x CH 0x%x\n", +		    expect_drdy, cmd, feature, count, +		    sector, head, cyl_low, cyl_hi));  		return (FALSE);  	} @@ -1717,10 +1765,10 @@ ata_command(  	 * wait for DRDY before continuing  	 */  	(void) ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2, -			ATS_DRDY, ATS_BSY, /* okay */ -			ATS_ERR, ATS_BSY, /* cmd failed */ -			ATS_DF, ATS_BSY, /* drive failed */ -			busy_wait); +	    ATS_DRDY, ATS_BSY, /* okay */ +	    ATS_ERR, ATS_BSY, /* cmd failed */ +	    ATS_DF, ATS_BSY, /* drive failed */ +	    busy_wait);  	/* read status to clear IRQ, and check for error */  	status =  ddi_get8(io_hdl1, ata_ctlp->ac_status); @@ -1730,12 +1778,12 @@ ata_command(  	if (!silent) {  		ADBG_ERROR(("ata_command status 0x%x error 0x%x " -			    "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x  " -			    "S 0x%x H 0x%x CL 0x%x CH 0x%x\n", -			    ddi_get8(io_hdl1, ata_ctlp->ac_status), -			    ddi_get8(io_hdl1, ata_ctlp->ac_error), -			    expect_drdy, cmd, feature, count, -			    sector, head, cyl_low, cyl_hi)); +		    "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x  " +		    "S 0x%x H 0x%x CL 0x%x CH 0x%x\n", +		    ddi_get8(io_hdl1, ata_ctlp->ac_status), +		    ddi_get8(io_hdl1, ata_ctlp->ac_error), +		    expect_drdy, cmd, feature, count, +		    sector, head, cyl_low, cyl_hi));  	}  	return (FALSE);  } @@ -1758,8 +1806,8 @@ ata_set_feature(  	int		 rc;  	rc = ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, ata_set_feature_wait, -		ATC_SET_FEAT, feature, value, 0, 0, 0, 0); -		/* feature, count, sector, head, cyl_low, cyl_hi */ +	    ATC_SET_FEAT, feature, value, 0, 0, 0, 0); +	/* feature, count, sector, head, cyl_low, cyl_hi */  	if (rc) {  		return (TRUE); @@ -1784,8 +1832,8 @@ ata_flush_cache(  {  	/* this command is optional so fail silently */  	return (ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, -			    ata_flush_cache_wait, -			    ATC_FLUSH_CACHE, 0, 0, 0, 0, 0, 0)); +	    ata_flush_cache_wait, +	    ATC_FLUSH_CACHE, 0, 0, 0, 0, 0, 0));  }  /* @@ -1812,7 +1860,6 @@ ata_setup_ioaddr(  	caddr_t		 *bm_addrp)  {  	ddi_device_acc_attr_t dev_attr; -	char	*bufp;  	int	 rnumber;  	int	 rc;  	off_t	 regsize; @@ -1824,14 +1871,14 @@ ata_setup_ioaddr(  	rc = ddi_dev_regsize(dip, 0, ®size);  	if (rc != DDI_SUCCESS || regsize <= AT_CMD) {  		ADBG_INIT(("ata_setup_ioaddr(1): rc %d regsize %lld\n", -			    rc, (long long)regsize)); +		    rc, (long long)regsize));  		return (FALSE);  	}  	rc = ddi_dev_regsize(dip, 1, ®size);  	if (rc != DDI_SUCCESS || regsize <= AT_ALTSTATUS) {  		ADBG_INIT(("ata_setup_ioaddr(2): rc %d regsize %lld\n", -			    rc, (long long)regsize)); +		    rc, (long long)regsize));  		return (FALSE);  	} @@ -1859,24 +1906,15 @@ ata_setup_ioaddr(  	/* else, it's ISA or PCI-IDE, check further */  	rnumber = 0; -	rc = ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(dip), -				    DDI_PROP_DONTPASS, "device_type", &bufp); -	if (rc != DDI_PROP_SUCCESS) { -		ADBG_ERROR(("ata_setup_ioaddr !device_type\n")); -		goto not_pciide; -	} - -	if (strcmp(bufp, "pci-ide") != 0) { +	if (!ata_is_pci(dip)) {  		/*  		 * If it's not a PCI-IDE, there are only two reg tuples  		 * and the first one contains the I/O base (170 or 1f0)  		 * rather than the controller instance number.  		 */  		ADBG_TRACE(("ata_setup_ioaddr !pci-ide\n")); -		ddi_prop_free(bufp);  		goto not_pciide;  	} -	ddi_prop_free(bufp);  	/* @@ -1889,7 +1927,7 @@ ata_setup_ioaddr(  	rc = ddi_dev_regsize(dip, 2, ®size);  	if (rc != DDI_SUCCESS || regsize < 8) {  		ADBG_INIT(("ata_setup_ioaddr(3): rc %d regsize %lld\n", -			    rc, (long long)regsize)); +		    rc, (long long)regsize));  		goto not_pciide;  	} @@ -1898,7 +1936,7 @@ ata_setup_ioaddr(  	if (rc != DDI_SUCCESS) {  		/* map failed, try to use in non-pci-ide mode */  		ADBG_WARN(("ata_setup_ioaddr bus master map failed, rc=0x%x\n", -			rc)); +		    rc));  		*bm_hdlp = NULL;  	} @@ -1908,7 +1946,7 @@ not_pciide:  	 */  	rc = ddi_regs_map_setup(dip, rnumber, addr1p, 0, 0, &dev_attr, -				handle1p); +	    handle1p);  	if (rc != DDI_SUCCESS) {  		cmn_err(CE_WARN, "ata: reg tuple 0 map failed, rc=0x%x\n", rc); @@ -1930,7 +1968,7 @@ not_pciide:  	 * map the upper control block registers  	 */  	rc = ddi_regs_map_setup(dip, rnumber + 1, addr2p, 0, 0, &dev_attr, -				handle2p); +	    handle2p);  	if (rc == DDI_SUCCESS)  		return (TRUE); @@ -2010,7 +2048,7 @@ ata_init_pciide(  	if (ata_check_pciide_blacklist(dip, ATA_BL_NODMA)) {  		ata_ctlp->ac_pciide_bm = FALSE;  		ata_cntrl_DMA_sel_msg = -			"cntrl blacklisted/DMA engine broken"; +		    "cntrl blacklisted/DMA engine broken";  		return;  	} @@ -2023,11 +2061,11 @@ ata_init_pciide(  	 */  	class_code = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), -		DDI_PROP_DONTPASS, "class-code", 0); +	    DDI_PROP_DONTPASS, "class-code", 0);  	if ((class_code & PCIIDE_BM_CAP_MASK) != PCIIDE_BM_CAP_MASK) {  		ata_ctlp->ac_pciide_bm = FALSE;  		ata_cntrl_DMA_sel_msg = -			"cntrl not Bus Master DMA capable"; +		    "cntrl not Bus Master DMA capable";  		return;  	} @@ -2036,7 +2074,7 @@ ata_init_pciide(  	 * between channels  	 */  	status = ddi_get8(ata_ctlp->ac_bmhandle, -			(uchar_t *)ata_ctlp->ac_bmaddr + PCIIDE_BMISX_REG); +	    (uchar_t *)ata_ctlp->ac_bmaddr + PCIIDE_BMISX_REG);  	/*  	 * Some motherboards have CSB5's that are wired "to emulate CSB4 mode".  	 * In such a mode, the simplex bit is asserted,  but in fact testing @@ -2138,7 +2176,7 @@ ata_init_drive_pcidma(  	}  	ata_options = ddi_prop_get_int(DDI_DEV_T_ANY, ata_ctlp->ac_dip, -			0, "ata-options", 0); +	    0, "ata-options", 0);  	if (!(ata_options & ATA_OPTIONS_DMA)) {  		/* @@ -2146,7 +2184,7 @@ ata_init_drive_pcidma(  		 * DMA is not enabled by this property  		 */  		ata_dev_DMA_sel_msg = -			"disabled by \"ata-options\" property"; +		    "disabled by \"ata-options\" property";  		return (ATA_DMA_OFF);  	} @@ -2178,13 +2216,13 @@ ata_init_drive_pcidma(  	}  	dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip, -		0, "ata-dma-enabled", TRUE); +	    0, "ata-dma-enabled", TRUE);  	disk_dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip, -		0, "ata-disk-dma-enabled", TRUE); +	    0, "ata-disk-dma-enabled", TRUE);  	cd_dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip, -		0, "atapi-cd-dma-enabled", FALSE); +	    0, "atapi-cd-dma-enabled", FALSE);  	atapi_dma = ata_prop_lookup_int(DDI_DEV_T_ANY, tdip, -		0, "atapi-other-dma-enabled", TRUE); +	    0, "atapi-other-dma-enabled", TRUE);  	if (dma == FALSE) {  		cmn_err(CE_CONT, "?ata_init_drive_pcidma: " @@ -2288,7 +2326,7 @@ ata_prop_create(  	if (strcmp("atapi", name) == 0) {  		rc =  ndi_prop_update_string(DDI_DEV_T_NONE, tgt_dip, -			"variant", name); +		    "variant", name);  		if (rc != DDI_PROP_SUCCESS)  			return (FALSE);  	} @@ -2297,7 +2335,7 @@ ata_prop_create(  		return (TRUE);  	rc =  ndi_prop_update_byte_array(DDI_DEV_T_NONE, tgt_dip, name, -		(uchar_t *)&ata_drvp->ad_id, sizeof (ata_drvp->ad_id)); +	    (uchar_t *)&ata_drvp->ad_id, sizeof (ata_drvp->ad_id));  	if (rc != DDI_PROP_SUCCESS) {  		ADBG_ERROR(("ata_prop_create failed, rc=%d\n", rc));  	} @@ -2469,7 +2507,7 @@ ata_ctlr_fsm(  	 * Start ARQ pkt if necessary  	 */  	if ((ata_pktp->ap_flags & AP_ARQ_NEEDED) == AP_ARQ_NEEDED && -			(ata_pktp->ap_status & ATS_ERR)) { +	    (ata_pktp->ap_status & ATS_ERR)) {  		/* set controller state back to active */  		ata_ctlp->ac_state = current_state; @@ -2552,7 +2590,7 @@ ata_start_arq(  	arq_pktp->ap_resid = senselen;  	arq_pktp->ap_flags = AP_ATAPI | AP_READ;  	arq_pktp->ap_cdb_pad = -	((unsigned)(ata_drvp->ad_cdb_len - arq_pktp->ap_cdb_len)) >> 1; +	    ((unsigned)(ata_drvp->ad_cdb_len - arq_pktp->ap_cdb_len)) >> 1;  	bytes = min(senselen, ATAPI_MAX_BYTES_PER_DRQ);  	arq_pktp->ap_hicyl = (uchar_t)(bytes >> 8); @@ -2591,7 +2629,7 @@ ata_reset_bus(  	fsm_func = ATA_FSM_RESET;  	for (watchdog = ata_reset_bus_watchdog; watchdog > 0; watchdog--) {  		switch (ata_ctlr_fsm(fsm_func, ata_ctlp, NULL, NULL, -						&DoneFlg)) { +		    &DoneFlg)) {  		case ATA_FSM_RC_OKAY:  			rc = TRUE;  			goto fsm_done; @@ -2737,7 +2775,7 @@ wait_for_not_busy:  	 */  	usecs_left = (deadline - gethrtime()) / 1000;  	(void) ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY, -		ATS_ERR, ATS_BSY, ATS_DF, ATS_BSY, usecs_left); +	    ATS_ERR, ATS_BSY, ATS_DF, ATS_BSY, usecs_left);  	return (TRUE);  } @@ -2987,7 +3025,7 @@ ata_hba_start(  	request_started = FALSE;  	for (watchdog = ata_hba_start_watchdog; watchdog > 0; watchdog--) {  		switch (ata_ctlr_fsm(fsm_func, ata_ctlp, ata_drvp, ata_pktp, -				NULL)) { +		    NULL)) {  		case ATA_FSM_RC_OKAY:  			request_started = TRUE;  			goto fsm_done; @@ -3037,15 +3075,15 @@ ata_check_pciide_blacklist(  	vendorid = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), -				    DDI_PROP_DONTPASS, "vendor-id", 0); +	    DDI_PROP_DONTPASS, "vendor-id", 0);  	deviceid = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), -				    DDI_PROP_DONTPASS, "device-id", 0); +	    DDI_PROP_DONTPASS, "device-id", 0);  	/*  	 * first check for a match in the "pci-ide-blacklist" property  	 */  	rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, -		"pci-ide-blacklist", &propp, &count); +	    "pci-ide-blacklist", &propp, &count);  	if (rc == DDI_PROP_SUCCESS) {  		count = (count * sizeof (uint_t)) / sizeof (pcibl_t); @@ -3053,12 +3091,12 @@ ata_check_pciide_blacklist(  		while (count--) {  			/* check for matching ID */  			if ((vendorid & blp->b_vmask) -					!= (blp->b_vendorid & blp->b_vmask)) { +			    != (blp->b_vendorid & blp->b_vmask)) {  				blp++;  				continue;  			}  			if ((deviceid & blp->b_dmask) -					!= (blp->b_deviceid & blp->b_dmask)) { +			    != (blp->b_deviceid & blp->b_dmask)) {  				blp++;  				continue;  			} @@ -3099,7 +3137,7 @@ ata_check_drive_blacklist(  	for (blp = ata_drive_blacklist; blp->b_model; blp++) {  		if (!ata_strncmp(blp->b_model, aidp->ai_model, -				sizeof (aidp->ai_model))) +		    sizeof (aidp->ai_model)))  			continue;  		if (blp->b_flags & flags)  			return (TRUE); @@ -3152,7 +3190,7 @@ ata_queue_cmd(  	 * ap_start function is called.  	 */  	rc = ghd_transport(&ata_ctlp->ac_ccc, gcmdp, gcmdp->cmd_gtgtp, -		0, TRUE, NULL); +	    0, TRUE, NULL);  	if (rc != TRAN_ACCEPT) {  		/* this should never, ever happen */ @@ -3230,7 +3268,7 @@ ata_check_revert_to_defaults(  	/* look for a disk-specific "revert" property" */  	propval = ddi_getprop(DDI_DEV_T_ANY, ata_ctlp->ac_dip, -		DDI_PROP_DONTPASS, prop_buf, -1); +	    DDI_PROP_DONTPASS, prop_buf, -1);  	if (propval == 0)  		return (FALSE);  	else if (propval != -1) @@ -3238,7 +3276,7 @@ ata_check_revert_to_defaults(  	/* look for a global "revert" property" */  	propval = ddi_getprop(DDI_DEV_T_ANY, ata_ctlp->ac_dip, -		0, ATA_REVERT_PROP_GLOBAL, -1); +	    0, ATA_REVERT_PROP_GLOBAL, -1);  	if (propval == 0)  		return (FALSE);  	else if (propval != -1) @@ -3262,7 +3300,7 @@ ata_show_transfer_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp)  		}  		ATAPRT(("?\tPIO mode %d selected\n",  		    (ata_drvp->ad_id.ai_advpiomode & ATAC_ADVPIO_4_SUP) == -			ATAC_ADVPIO_4_SUP ? 4 : 3)); +		    ATAC_ADVPIO_4_SUP ? 4 : 3));  	} else {  		/* Using DMA */  		if (ata_drvp->ad_id.ai_dworddma & ATAC_MDMA_SEL_MASK) { @@ -3271,10 +3309,10 @@ ata_show_transfer_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp)  			 * selected, not both.  			 */  			ATAPRT(("?\tMultiwordDMA mode %d selected\n", -			(ata_drvp->ad_id.ai_dworddma & ATAC_MDMA_2_SEL) == +			    (ata_drvp->ad_id.ai_dworddma & ATAC_MDMA_2_SEL) ==  			    ATAC_MDMA_2_SEL ? 2 :  			    (ata_drvp->ad_id.ai_dworddma & ATAC_MDMA_1_SEL) == -				ATAC_MDMA_1_SEL ? 1 : 0)); +			    ATAC_MDMA_1_SEL ? 1 : 0));  		} else {  			for (i = 0; i <= 6; i++) {  				if (ata_drvp->ad_id.ai_ultradma & @@ -3330,9 +3368,9 @@ ata_spec_init_controller(dev_info_t *dip)  	struct ata_ctl_spec	*ctlsp;  	vendor_id = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), -				    DDI_PROP_DONTPASS, "vendor-id", 0); +	    DDI_PROP_DONTPASS, "vendor-id", 0);  	device_id = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), -				    DDI_PROP_DONTPASS, "device-id", 0); +	    DDI_PROP_DONTPASS, "device-id", 0);  	/* Locate controller specific ops, if they exist */  	ctlsp = ata_cntrls_spec; @@ -3375,7 +3413,7 @@ ata_prop_lookup_int(dev_t match_dev, dev_info_t *dip,  	int proprc;  	proprc = ddi_prop_lookup_string(match_dev, dip, -		flags, name, &bufp); +	    flags, name, &bufp);  	if (proprc == DDI_PROP_SUCCESS) {  		cp = bufp; @@ -3390,3 +3428,287 @@ ata_prop_lookup_int(dev_t match_dev, dev_info_t *dip,  	return (rc);  } + +/* + * Initialize the power management components + */ +static void +ata_init_pm(dev_info_t *dip) +{ +	char		pmc_name[16]; +	char		*pmc[] = { +				NULL, +				"0=Sleep (PCI D3 State)", +				"3=PowerOn (PCI D0 State)", +				NULL +			}; +	int		instance; +	ata_ctl_t 	*ata_ctlp; + + +	instance = ddi_get_instance(dip); +	ata_ctlp = ddi_get_soft_state(ata_state, instance); +	ata_ctlp->ac_pm_support = 0; + +	/* check PCI capabilities */ +	if (!ata_is_pci(dip)) +		return; + +	(void) sprintf(pmc_name, "NAME=ata%d", instance); +	pmc[0] = pmc_name; + +#ifdef	ATA_USE_AUTOPM +	if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip, +	    "pm-components", pmc, 3) != DDI_PROP_SUCCESS) { +		return; +	} +#endif + +	ata_ctlp->ac_pm_support = 1; +	ata_ctlp->ac_pm_level = PM_LEVEL_D0; + +	ATA_BUSY_COMPONENT(dip, 0); +	if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) { +		(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components"); +	} +	ATA_IDLE_COMPONENT(dip, 0); +} + +/* + * resume the hard drive + */ +static void +ata_resume_drive(ata_drv_t *ata_drvp) +{ +	ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp; +	int drive_type; +	struct ata_id id; +	uint8_t udma; + +	ADBG_TRACE(("ata_resume_drive entered\n")); + +	drive_type = ata_drive_type(ata_drvp->ad_drive_bits, +	    ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1, +	    ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, +	    &id); +	if (drive_type == ATA_DEV_NONE) +		return; + +	/* Reset Ultra DMA mode */ +	udma = ATACM_UDMA_SEL(&ata_drvp->ad_id); +	if (udma != 0) { +		uint8_t mode; +		for (mode = 0; mode < 8; mode++) +			if (((1 << mode) & udma) != 0) +				break; +		ASSERT(mode != 8); + +		mode |= ATF_XFRMOD_UDMA; + +		if (!ata_set_feature(ata_ctlp, ata_drvp, ATSF_SET_XFRMOD, mode)) +			return; +	} + +	if (!ATAPIDRV(ata_drvp)) { +		if (!ata_disk_setup_parms(ata_ctlp, ata_drvp)) +			return; +		(void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_DIS_REVPOD, 0); +	} +} + +/* + * resume routine, it will be run when get the command + * DDI_RESUME at attach(9E) from system power management + */ +static int +ata_resume(dev_info_t *dip) +{ +	int		instance; +	ata_ctl_t 	*ata_ctlp; +	ddi_acc_handle_t io_hdl2; +	caddr_t		ioaddr2; + +	instance = ddi_get_instance(dip); +	ata_ctlp = ddi_get_soft_state(ata_state, instance); + +	if (!ata_ctlp->ac_pm_support) +		return (DDI_FAILURE); +	if (ata_ctlp->ac_pm_level == PM_LEVEL_D0) +		return (DDI_SUCCESS); + +	ATA_BUSY_COMPONENT(dip, 0); +	if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) == DDI_FAILURE) +		return (DDI_FAILURE); +	ATA_IDLE_COMPONENT(dip, 0); + +	/* enable interrupts from the device */ +	io_hdl2 = ata_ctlp->ac_iohandle2; +	ioaddr2 = ata_ctlp->ac_ioaddr2; +	ddi_put8(io_hdl2, (uchar_t *)ioaddr2 + AT_DEVCTL, ATDC_D3); +	ata_ctlp->ac_pm_level = PM_LEVEL_D0; + +	return (DDI_SUCCESS); +} + +/* + * suspend routine, it will be run when get the command + * DDI_SUSPEND at detach(9E) from system power management + */ +static int +ata_suspend(dev_info_t *dip) +{ +	int		instance; +	ata_ctl_t 	*ata_ctlp; +	ddi_acc_handle_t io_hdl2; + +	instance = ddi_get_instance(dip); +	ata_ctlp = ddi_get_soft_state(ata_state, instance); + +	if (!ata_ctlp->ac_pm_support) +		return (DDI_FAILURE); +	if (ata_ctlp->ac_pm_level == PM_LEVEL_D3) +		return (DDI_SUCCESS); + +	/* disable interrupts and turn the software reset bit on */ +	io_hdl2 = ata_ctlp->ac_iohandle2; +	ddi_put8(io_hdl2, ata_ctlp->ac_devctl, (ATDC_D3 | ATDC_SRST)); + +	(void) ata_reset_bus(ata_ctlp); +	(void) ata_change_power(dip, ATC_SLEEP); +	ata_ctlp->ac_pm_level = PM_LEVEL_D3; +	return (DDI_SUCCESS); +} + +int ata_save_pci_config = 0; +/* + * ata specific power management entry point, it was + * used to change the power management component + */ +static int +ata_power(dev_info_t *dip, int component, int level) +{ +	int		instance; +	ata_ctl_t 	*ata_ctlp; +	uint8_t		cmd; + +	ADBG_TRACE(("ata_power entered, component = %d, level = %d\n", +	    component, level)); + +	instance = ddi_get_instance(dip); +	ata_ctlp = ddi_get_soft_state(ata_state, instance); +	if (ata_ctlp == NULL || component != 0) +		return (DDI_FAILURE); + +	if (!ata_ctlp->ac_pm_support) +		return (DDI_FAILURE); + +	switch (level) { +	case PM_LEVEL_D0: +		if (ata_save_pci_config) +			(void) pci_restore_config_regs(dip); +		ata_ctlp->ac_pm_level = PM_LEVEL_D0; +		cmd = ATC_STANDBY_IM; +		break; +	case PM_LEVEL_D3: +		if (ata_save_pci_config) +			(void) pci_save_config_regs(dip); +		ata_ctlp->ac_pm_level = PM_LEVEL_D3; +		cmd = ATC_SLEEP; +		break; +	default: +		return (DDI_FAILURE); +	} +	return (ata_change_power(dip, cmd)); +} + +/* + * sent commands to ata controller to change the power level + */ +static int +ata_change_power(dev_info_t *dip, uint8_t cmd) +{ +	int		instance; +	ata_ctl_t 	*ata_ctlp; +	ata_drv_t	*ata_drvp; +	uchar_t		targ; +	struct ata_id 	id; +	uchar_t		lun; +	uchar_t		lastlun; + +	ADBG_TRACE(("ata_change_power entered, cmd = %d\n", cmd)); + +	instance = ddi_get_instance(dip); +	ata_ctlp = ddi_get_soft_state(ata_state, instance); +	/* +	 * Issue command on each disk device on the bus. +	 */ +	for (targ = 0; targ < ATA_MAXTARG; targ++) { +		ata_drvp = CTL2DRV(ata_ctlp, targ, 0); +		if (ata_drvp == NULL) +			continue; +		if (ata_drive_type(ata_drvp->ad_drive_bits, +		    ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1, +		    ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2, +		    &id) != ATA_DEV_DISK) +			continue; +		(void) ata_flush_cache(ata_ctlp, ata_drvp); +		if (!ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, 5 * 1000000, +		    cmd, 0, 0, 0, 0, 0, 0)) { +			cmn_err(CE_WARN, "!ata_controller - Can not put " +			    "drive %d in to power mode %u", targ, cmd); +			(void) ata_devo_reset(dip, DDI_RESET_FORCE); +			return (DDI_FAILURE); +		} +	} + +	if (cmd == ATC_SLEEP) +		return (DDI_SUCCESS); + +	for (targ = 0; targ < ATA_MAXTARG; targ++) { +		ata_drvp = CTL2DRV(ata_ctlp, targ, 0); +		if ((ata_drvp == NULL) || !(ata_drvp->ad_flags & AD_DISK)) +			continue; +		ata_resume_drive(ata_drvp); + +		if (ATAPIDRV(ata_drvp)) +			lastlun = ata_drvp->ad_id.ai_lastlun; +		else +			lastlun = 0; +		if (!ata_enable_atapi_luns) +			lastlun = 0; +		for (lun = 1; lun <= lastlun && lun < ATA_MAXLUN; lun++) { +			ata_drvp = CTL2DRV(ata_ctlp, targ, lun); +			if (ata_drvp != NULL) +				ata_resume_drive(ata_drvp); +		} +		(void) ata_software_reset(ata_ctlp); +	} + +	return (DDI_SUCCESS); +} + +/* + * return 1 when ata controller is a pci device, + * otherwise return 0 + */ +static int +ata_is_pci(dev_info_t *dip) +{ +	int rc; +	char *bufp; +	int ispci; + +	rc = ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(dip), +	    DDI_PROP_DONTPASS, "device_type", &bufp); + +	if (rc != DDI_PROP_SUCCESS) { +		ADBG_ERROR(("ata_is_pci !device_type\n")); +		return (0); +	} + +	ispci = (strcmp(bufp, "pci-ide") == 0); + +	ddi_prop_free(bufp); + +	return (ispci); +} diff --git a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.h b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.h index 1df1252b55..22aef7c97e 100644 --- a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.h +++ b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.h @@ -177,6 +177,15 @@ extern "C" {   * Feature register bits   */  #define	ATF_ATAPI_DMA	0x01	/* ATAPI DMA enable bit */ +#define	ATF_XFRMOD_UDMA	0x40	/* Ultra DMA mode	*/ +#define	ATACM_UDMA_SEL(id)	(((id)->ai_ultradma >> 8) & 0x7f) + +/* + * Set feature register definitions. + */ +#define	ATSF_SET_XFRMOD	0X03	/* Set transfer mode			  */ +#define	ATSF_DIS_REVPOD	0x66	/* Disable reverting to power on defaults */ +#define	ATSF_ENA_REVPOD	0xcc	/* Enable reverting to power on defaults  */  /*   * common bits and options for set features (ATC_SET_FEAT) @@ -281,6 +290,12 @@ typedef struct ata_ctl {  	struct ata_pkt	*ac_arq_pktp;	  /* pkt for performing ATAPI ARQ */  	struct ata_pkt	*ac_fault_pktp;	  /* pkt that caused ARQ */  	uchar_t		 ac_arq_cdb[6]; + +	/* +	 * Power Management +	 */ +	int		ac_pm_support; +	int		ac_pm_level;  } ata_ctl_t;  /* ac_flags (per-controller) */ diff --git a/usr/src/uts/intel/io/dktp/dcdev/dadk.c b/usr/src/uts/intel/io/dktp/dcdev/dadk.c index eaf5c28db0..5b99559cc3 100644 --- a/usr/src/uts/intel/io/dktp/dcdev/dadk.c +++ b/usr/src/uts/intel/io/dktp/dcdev/dadk.c @@ -73,6 +73,7 @@ static struct cmpkt *dadk_pktprep(struct dadk *dadkp, struct cmpkt *in_pktp,  static int  dadk_pkt(opaque_t com_data, struct buf *bp, int (*func)(caddr_t),      caddr_t arg);  static void dadk_transport(opaque_t com_data, struct buf *bp); +static int dadk_ctl_ioctl(struct dadk *, uint32_t, uintptr_t, int);  struct tgcom_objops dadk_com_ops = {  	nodev, @@ -336,6 +337,8 @@ dadk_init(opaque_t objp, opaque_t devp, opaque_t flcobjp, opaque_t queobjp,  	BBH_INIT(bbhobjp);  	dadkp->dad_flcobjp = flcobjp; +	mutex_init(&dadkp->dad_cmd_mutex, NULL, MUTEX_DRIVER, NULL); +	dadkp->dad_cmd_count = 0;  	return (FLC_INIT(flcobjp, &(dadkp->dad_com), queobjp, lkarg));  } @@ -364,6 +367,7 @@ dadk_cleanup(struct tgdk_obj *dkobjp)  		FLC_FREE(dadkp->dad_flcobjp);  		dadkp->dad_flcobjp = NULL;  	} +	mutex_destroy(&dadkp->dad_cmd_mutex);  }  /* ARGSUSED */ @@ -376,7 +380,7 @@ dadk_probe(opaque_t objp, int kmsflg)  	devp = dadkp->dad_sd;  	if (!devp->sd_inq || (devp->sd_inq->inq_dtype == DTYPE_NOTPRESENT) || -		(devp->sd_inq->inq_dtype == DTYPE_UNKNOWN)) { +	    (devp->sd_inq->inq_dtype == DTYPE_UNKNOWN)) {  		return (DDI_PROBE_FAILURE);  	} @@ -454,21 +458,23 @@ dadk_open(opaque_t objp, int flag)  			return (DDI_SUCCESS);  		}  	} else { -	    mutex_enter(&dadkp->dad_mutex); -	    dadkp->dad_iostate = DKIO_NONE; -	    cv_broadcast(&dadkp->dad_state_cv); -	    mutex_exit(&dadkp->dad_mutex); - -	    if (dadk_rmb_ioctl(dadkp, DCMD_START_MOTOR, 0, 0, DADK_SILENT) || -		dadk_rmb_ioctl(dadkp, DCMD_LOCK, 0, 0, DADK_SILENT) || -		dadk_rmb_ioctl(dadkp, DCMD_UPDATE_GEOM, 0, 0, DADK_SILENT)) { -		    return (DDI_FAILURE); -	    } - -	    mutex_enter(&dadkp->dad_mutex); -	    dadkp->dad_iostate = DKIO_INSERTED; -	    cv_broadcast(&dadkp->dad_state_cv); -	    mutex_exit(&dadkp->dad_mutex); +		mutex_enter(&dadkp->dad_mutex); +		dadkp->dad_iostate = DKIO_NONE; +		cv_broadcast(&dadkp->dad_state_cv); +		mutex_exit(&dadkp->dad_mutex); + +		if (dadk_rmb_ioctl(dadkp, DCMD_START_MOTOR, 0, 0, +		    DADK_SILENT) || +		    dadk_rmb_ioctl(dadkp, DCMD_LOCK, 0, 0, DADK_SILENT) || +		    dadk_rmb_ioctl(dadkp, DCMD_UPDATE_GEOM, 0, 0, +		    DADK_SILENT)) { +			return (DDI_FAILURE); +		} + +		mutex_enter(&dadkp->dad_mutex); +		dadkp->dad_iostate = DKIO_INSERTED; +		cv_broadcast(&dadkp->dad_state_cv); +		mutex_exit(&dadkp->dad_mutex);  	}  	/* @@ -482,20 +488,20 @@ dadk_open(opaque_t objp, int flag)  	 * is added to the driver to change WCE, dad_wce  	 * must be updated appropriately.  	 */ -	error = CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETWCE, +	error = dadk_ctl_ioctl(dadkp, DIOCTL_GETWCE,  	    (uintptr_t)&wce, FKIOCTL | FNATIVE);  	mutex_enter(&dadkp->dad_mutex);  	dadkp->dad_wce = (error != 0) || (wce != 0);  	mutex_exit(&dadkp->dad_mutex);  	/* logical disk geometry */ -	CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETGEOM, +	(void) dadk_ctl_ioctl(dadkp, DIOCTL_GETGEOM,  	    (uintptr_t)&dadkp->dad_logg, FKIOCTL | FNATIVE);  	if (dadkp->dad_logg.g_cap == 0)  		return (DDI_FAILURE);  	/* get physical disk geometry */ -	CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETPHYGEOM, +	(void) dadk_ctl_ioctl(dadkp, DIOCTL_GETPHYGEOM,  	    (uintptr_t)&dadkp->dad_phyg, FKIOCTL | FNATIVE);  	if (dadkp->dad_phyg.g_cap == 0)  		return (DDI_FAILURE); @@ -507,7 +513,7 @@ dadk_open(opaque_t objp, int flag)  	/* start profiling */  	FLC_START_KSTAT(dadkp->dad_flcobjp, "disk", -		ddi_get_instance(CTL_DIP_DEV(dadkp->dad_ctlobjp))); +	    ddi_get_instance(CTL_DIP_DEV(dadkp->dad_ctlobjp)));  	return (DDI_SUCCESS);  } @@ -534,7 +540,8 @@ dadk_setcap(struct dadk *dadkp)  	/* set sec,block shift factor - (512->0, 1024->1, 2048->2, etc.) */  	totsize >>= SCTRSHFT; -	for (i = 0; totsize != 1; i++, totsize >>= 1); +	for (i = 0; totsize != 1; i++, totsize >>= 1) +		;  	dadkp->dad_blkshf = i;  	dadkp->dad_secshf = i + SCTRSHFT;  } @@ -594,14 +601,14 @@ dadk_create_errstats(struct dadk *dadkp, int instance)  	dep->dadk_model.value.c[0] = 0;  	dadk_ioc_string.is_buf = &dep->dadk_model.value.c[0];  	dadk_ioc_string.is_size = sizeof (dep->dadk_model.value.c); -	CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETMODEL, +	(void) dadk_ctl_ioctl(dadkp, DIOCTL_GETMODEL,  	    (uintptr_t)&dadk_ioc_string, FKIOCTL | FNATIVE);  	/* get serial */  	dep->dadk_serial.value.c[0] = 0;  	dadk_ioc_string.is_buf = &dep->dadk_serial.value.c[0];  	dadk_ioc_string.is_size = sizeof (dep->dadk_serial.value.c); -	CTL_IOCTL(dadkp->dad_ctlobjp, DIOCTL_GETSERIAL, +	(void) dadk_ctl_ioctl(dadkp, DIOCTL_GETSERIAL,  	    (uintptr_t)&dadk_ioc_string, FKIOCTL | FNATIVE);  	/* Get revision */ @@ -659,6 +666,9 @@ dadk_strategy(opaque_t objp, struct buf *bp)  	}  	SET_BP_SEC(bp, (LBLK2SEC(GET_BP_SEC(bp), dadkp->dad_blkshf))); +	mutex_enter(&dadkp->dad_cmd_mutex); +	dadkp->dad_cmd_count++; +	mutex_exit(&dadkp->dad_cmd_mutex);  	FLC_ENQUE(dadkp->dad_flcobjp, bp);  	return (DDI_SUCCESS); @@ -715,7 +725,7 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,  	switch (cmd) {  	case DKIOCGETDEF: -	    { +		{  		struct buf	*bp;  		int		err, head;  		unsigned char	*secbuf; @@ -752,6 +762,9 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,  		bp->b_forw = (struct buf *)dadkp;  		bp->b_back = (struct buf *)DCMD_GETDEF; +		mutex_enter(&dadkp->dad_cmd_mutex); +		dadkp->dad_cmd_count++; +		mutex_exit(&dadkp->dad_cmd_mutex);  		FLC_ENQUE(dadkp->dad_flcobjp, bp);  		err = biowait(bp);  		if (!err) { @@ -762,9 +775,9 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,  		kmem_free(secbuf, NBPSCTR);  		freerbuf(bp);  		return (err); -	    } +		}  	case DIOCTL_RWCMD: -	    { +		{  		struct dadkio_rwcmd *rwcmdp;  		int status, rw; @@ -794,8 +807,8 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,  				return (status);  			default:  				return (EINVAL); +			}  		} -	    }  	case DKIOC_UPDATEFW:  		/* @@ -805,7 +818,7 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,  		if (PRIV_POLICY(cred_p, PRIV_ALL, B_FALSE, EPERM, NULL) != 0)  			return (EPERM);  		else -			return (CTL_IOCTL(dadkp->dad_ctlobjp, cmd, arg, flag)); +			return (dadk_ctl_ioctl(dadkp, cmd, arg, flag));  	case DKIOCFLUSHWRITECACHE:  		{ @@ -884,6 +897,9 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,  			CTL_IOSETUP(dadkp->dad_ctlobjp, pktp); +			mutex_enter(&dadkp->dad_cmd_mutex); +			dadkp->dad_cmd_count++; +			mutex_exit(&dadkp->dad_cmd_mutex);  			FLC_ENQUE(dadkp->dad_flcobjp, bp);  			if (is_sync) { @@ -894,16 +910,16 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,  		}  	default:  		if (!dadkp->dad_rmb) -			return (CTL_IOCTL(dadkp->dad_ctlobjp, cmd, arg, flag)); +			return (dadk_ctl_ioctl(dadkp, cmd, arg, flag));  	}  	switch (cmd) {  	case CDROMSTOP:  		return (dadk_rmb_ioctl(dadkp, DCMD_STOP_MOTOR, 0, -			0, DADK_SILENT)); +		    0, DADK_SILENT));  	case CDROMSTART:  		return (dadk_rmb_ioctl(dadkp, DCMD_START_MOTOR, 0, -			0, DADK_SILENT)); +		    0, DADK_SILENT));  	case DKIOCLOCK:  		return (dadk_rmb_ioctl(dadkp, DCMD_LOCK, 0, 0, DADK_SILENT));  	case DKIOCUNLOCK: @@ -914,11 +930,11 @@ dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag,  			int ret;  			if (ret = dadk_rmb_ioctl(dadkp, DCMD_UNLOCK, 0, 0, -				DADK_SILENT)) { +			    DADK_SILENT)) {  				return (ret);  			}  			if (ret = dadk_rmb_ioctl(dadkp, DCMD_EJECT, 0, 0, -				DADK_SILENT)) { +			    DADK_SILENT)) {  				return (ret);  			}  			mutex_enter(&dadkp->dad_mutex); @@ -1036,7 +1052,7 @@ dadk_iob_alloc(opaque_t objp, daddr_t blkno, ssize_t xfer, int kmsflg)  	iobp->b_psec  = LBLK2SEC(blkno, dadkp->dad_blkshf);  	iobp->b_pbyteoff = (blkno & ((1<<dadkp->dad_blkshf) - 1)) << SCTRSHFT;  	iobp->b_pbytecnt = ((iobp->b_pbyteoff + xfer + dadkp->DAD_SECSIZ - 1) -				>> dadkp->dad_secshf) << dadkp->dad_secshf; +	    >> dadkp->dad_secshf) << dadkp->dad_secshf;  	bp->b_un.b_addr = 0;  	/* @@ -1107,6 +1123,9 @@ dadk_iob_xfer(opaque_t objp, struct tgdk_iob *iobp, int rw)  	bp->b_resid = 0;  	/* call flow control */ +	mutex_enter(&dadkp->dad_cmd_mutex); +	dadkp->dad_cmd_count++; +	mutex_exit(&dadkp->dad_cmd_mutex);  	FLC_ENQUE(dadkp->dad_flcobjp, bp);  	err = biowait(bp); @@ -1253,16 +1272,15 @@ dadk_ioretry(struct cmpkt *pktp, int action)  		if (pktp->cp_retry++ < DADK_RETRY_COUNT) {  			CTL_IOSETUP(dadkp->dad_ctlobjp, pktp);  			if (CTL_TRANSPORT(dadkp->dad_ctlobjp, pktp) == -				CTL_SEND_SUCCESS) { +			    CTL_SEND_SUCCESS) {  				return (JUST_RETURN);  			}  			gda_log(dadkp->dad_sd->sd_dev, dadk_name, -				CE_WARN, -				"transport of command fails\n"); +			    CE_WARN, "transport of command fails\n");  		} else  			gda_log(dadkp->dad_sd->sd_dev, -				dadk_name, CE_WARN, -				"exceeds maximum number of retries\n"); +			    dadk_name, CE_WARN, +			    "exceeds maximum number of retries\n");  		bioerror(pktp->cp_bp, ENXIO);  		/*FALLTHROUGH*/  	case COMMAND_DONE_ERROR: @@ -1378,7 +1396,7 @@ dadk_chkerr(struct cmpkt *pktp)  	if (pktp->cp_retry) {  		err_blkno = pktp->cp_srtsec + ((pktp->cp_bytexfer - -			pktp->cp_resid) >> dadkp->dad_secshf); +		    pktp->cp_resid) >> dadkp->dad_secshf);  	} else  		err_blkno = -1; @@ -1468,11 +1486,10 @@ dadk_recorderr(struct cmpkt *pktp, struct dadkio_rwcmd *rwcmdp)  	rwcmdp->status.failed_blk = rwcmdp->blkaddr + -		((pktp->cp_bytexfer - -		pktp->cp_resid) >> dadkp->dad_secshf); +	    ((pktp->cp_bytexfer - pktp->cp_resid) >> dadkp->dad_secshf);  	rwcmdp->status.resid = pktp->cp_bp->b_resid + -		pktp->cp_byteleft - pktp->cp_bytexfer + pktp->cp_resid; +	    pktp->cp_byteleft - pktp->cp_bytexfer + pktp->cp_resid;  	switch ((int)(* (char *)pktp->cp_scbp)) {  	case DERR_AMNF:  	case DERR_ABORT: @@ -1504,14 +1521,22 @@ dadk_recorderr(struct cmpkt *pktp, struct dadkio_rwcmd *rwcmdp)  	if (rwcmdp->flags & DADKIO_FLAG_SILENT)  		return;  	gda_errmsg(dadkp->dad_sd, pktp, dadk_name, dadk_errtab[scb].d_severity, -		rwcmdp->blkaddr, rwcmdp->status.failed_blk, -		dadk_cmds, dadk_sense); +	    rwcmdp->blkaddr, rwcmdp->status.failed_blk, +	    dadk_cmds, dadk_sense);  }  /*ARGSUSED*/  static void  dadk_polldone(struct buf *bp)  { +	struct cmpkt *pktp; +	struct dadk *dadkp; + +	pktp  = GDA_BP_PKT(bp); +	dadkp = PKT2DADK(pktp); +	mutex_enter(&dadkp->dad_cmd_mutex); +	dadkp->dad_cmd_count--; +	mutex_exit(&dadkp->dad_cmd_mutex);  }  static void @@ -1544,6 +1569,9 @@ dadk_iodone(struct buf *bp)  	if (pktp->cp_private)  		BBH_FREEHANDLE(dadkp->dad_bbhobjp, pktp->cp_private);  	gda_free(dadkp->dad_ctlobjp, pktp, NULL); +	mutex_enter(&dadkp->dad_cmd_mutex); +	dadkp->dad_cmd_count--; +	mutex_exit(&dadkp->dad_cmd_mutex);  	biodone(bp);  } @@ -1558,7 +1586,7 @@ dadk_check_media(opaque_t objp, int *state)  #ifdef DADK_DEBUG  	if (dadk_debug & DSTATE)  		PRF("dadk_check_media: user state %x disk state %x\n", -			*state, dadkp->dad_iostate); +		    *state, dadkp->dad_iostate);  #endif  	/*  	 * If state already changed just return @@ -1676,7 +1704,7 @@ dadk_rmb_ioctl(struct dadk *dadkp, int cmd, intptr_t arg, int flags, int silent)  	bp->b_forw  = (struct buf *)dadkp->dad_flcobjp;  	pktp->cp_passthru = (opaque_t)(intptr_t)silent; -	err = CTL_IOCTL(dadkp->dad_ctlobjp, cmd, (uintptr_t)pktp, flags); +	err = dadk_ctl_ioctl(dadkp, cmd, (uintptr_t)pktp, flags);  	freerbuf(bp);  	gda_free(dadkp->dad_ctlobjp, pktp, NULL);  	return (err); @@ -1698,6 +1726,9 @@ dadk_rmb_iodone(struct buf *bp)  	/* Start next one */  	FLC_DEQUE(dadkp->dad_flcobjp, bp); +	mutex_enter(&dadkp->dad_cmd_mutex); +	dadkp->dad_cmd_count--; +	mutex_exit(&dadkp->dad_cmd_mutex);  	biodone(bp);  } @@ -1769,5 +1800,42 @@ dadk_dk(struct dadk *dadkp, struct dadkio_rwcmd *rwcmdp, struct buf *bp)  	(void) dadk_ioprep(dadkp, pktp); +	mutex_enter(&dadkp->dad_cmd_mutex); +	dadkp->dad_cmd_count++; +	mutex_exit(&dadkp->dad_cmd_mutex);  	FLC_ENQUE(dadkp->dad_flcobjp, bp);  } + +/* + * There is no existing way to notify cmdk module + * when the command completed, so add this function + * to calculate how many on-going commands. + */ +int +dadk_getcmds(opaque_t objp) +{ +	struct dadk *dadkp = (struct dadk *)objp; +	int count; + +	mutex_enter(&dadkp->dad_cmd_mutex); +	count = dadkp->dad_cmd_count; +	mutex_exit(&dadkp->dad_cmd_mutex); +	return (count); +} + +/* + * this function was used to calc the cmd for CTL_IOCTL + */ +static int +dadk_ctl_ioctl(struct dadk *dadkp, uint32_t cmd, uintptr_t arg, int flag) +{ +	int error; +	mutex_enter(&dadkp->dad_cmd_mutex); +	dadkp->dad_cmd_count++; +	mutex_exit(&dadkp->dad_cmd_mutex); +	error = CTL_IOCTL(dadkp->dad_ctlobjp, cmd, arg, flag); +	mutex_enter(&dadkp->dad_cmd_mutex); +	dadkp->dad_cmd_count--; +	mutex_exit(&dadkp->dad_cmd_mutex); +	return (error); +} diff --git a/usr/src/uts/intel/io/dktp/disk/cmdk.c b/usr/src/uts/intel/io/dktp/disk/cmdk.c index 4ce5a60250..d14946bcf2 100644 --- a/usr/src/uts/intel/io/dktp/disk/cmdk.c +++ b/usr/src/uts/intel/io/dktp/disk/cmdk.c @@ -163,6 +163,11 @@ static int cmdkprobe(dev_info_t *dip);  static int cmdkattach(dev_info_t *dip, ddi_attach_cmd_t cmd);  static int cmdkdetach(dev_info_t *dip, ddi_detach_cmd_t cmd); +static void cmdk_setup_pm(dev_info_t *dip, struct cmdk *dkp); +static int cmdkresume(dev_info_t *dip); +static int cmdksuspend(dev_info_t *dip); +static int cmdkpower(dev_info_t *dip, int component, int level); +  struct dev_ops cmdk_ops = {  	DEVO_REV, 		/* devo_rev, */  	0, 			/* refcnt  */ @@ -173,7 +178,8 @@ struct dev_ops cmdk_ops = {  	cmdkdetach,		/* detach */  	nodev, 			/* reset */  	&cmdk_cb_ops, 		/* driver operations */ -	(struct bus_ops *)0	/* bus operations */ +	(struct bus_ops *)0,	/* bus operations */ +	cmdkpower		/* power */  };  /* @@ -322,13 +328,22 @@ cmdkattach(dev_info_t *dip, ddi_attach_cmd_t cmd)  	struct		cmdk *dkp;  	char 		*node_type; -	if (cmd != DDI_ATTACH) +	switch (cmd) { +	case DDI_ATTACH: +		break; +	case DDI_RESUME: +		return (cmdkresume(dip)); +	default:  		return (DDI_FAILURE); +	}  	instance = ddi_get_instance(dip);  	if (!(dkp = ddi_get_soft_state(cmdk_state, instance)))  		return (DDI_FAILURE); +	dkp->dk_pm_level = CMDK_SPINDLE_UNINIT; +	mutex_init(&dkp->dk_mutex, NULL, MUTEX_DRIVER, NULL); +  	mutex_enter(&dkp->dk_mutex);  	/* dadk_attach is an empty function that only returns SUCCESS */ @@ -386,6 +401,13 @@ cmdkattach(dev_info_t *dip, ddi_attach_cmd_t cmd)  	    DDI_KERNEL_IOCTL, NULL, 0);  	ddi_report_dev(dip); +	/* +	 * Initialize power management +	 */ +	mutex_init(&dkp->dk_pm_mutex, NULL, MUTEX_DRIVER, NULL); +	cv_init(&dkp->dk_suspend_cv,   NULL, CV_DRIVER, NULL); +	cmdk_setup_pm(dip, dkp); +  	return (DDI_SUCCESS);  fail1: @@ -408,7 +430,13 @@ cmdkdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)  	int 		instance;  	int		max_instance; -	if (cmd != DDI_DETACH) { +	switch (cmd) { +	case DDI_DETACH: +		/* return (DDI_FAILURE); */ +		break; +	case DDI_SUSPEND: +		return (cmdksuspend(dip)); +	default:  #ifdef CMDK_DEBUG  		if (cmdk_debug & DIO) {  			PRF("cmdkdetach: cmd = %d unknown\n", cmd); @@ -454,6 +482,8 @@ cmdkdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)  	mutex_exit(&dkp->dk_mutex);  	mutex_destroy(&dkp->dk_mutex);  	rw_destroy(&dkp->dk_bbh_mutex); +	mutex_destroy(&dkp->dk_pm_mutex); +	cv_destroy(&dkp->dk_suspend_cv);  	ddi_soft_state_free(cmdk_state, instance);  	return (DDI_SUCCESS); @@ -490,6 +520,145 @@ cmdkinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)  	return (DDI_SUCCESS);  } +/* + * Initialize the power management components + */ +static void +cmdk_setup_pm(dev_info_t *dip, struct cmdk *dkp) +{ +	char *pm_comp[] = { "NAME=cmdk", "0=off", "1=on", NULL }; + +	/* +	 * Since the cmdk device does not the 'reg' property, +	 * cpr will not call its DDI_SUSPEND/DDI_RESUME entries. +	 * The following code is to tell cpr that this device +	 * DOES need to be suspended and resumed. +	 */ +	(void) ddi_prop_update_string(DDI_DEV_T_NONE, dip, +	    "pm-hardware-state", "needs-suspend-resume"); + +	if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip, +	    "pm-components", pm_comp, 3) == DDI_PROP_SUCCESS) { +		if (pm_raise_power(dip, 0, CMDK_SPINDLE_ON) == DDI_SUCCESS) { +			mutex_enter(&dkp->dk_pm_mutex); +			dkp->dk_pm_level = CMDK_SPINDLE_ON; +			dkp->dk_pm_is_enabled = 1; +			mutex_exit(&dkp->dk_pm_mutex); +		} else { +			mutex_enter(&dkp->dk_pm_mutex); +			dkp->dk_pm_level = CMDK_SPINDLE_OFF; +			dkp->dk_pm_is_enabled = 0; +			mutex_exit(&dkp->dk_pm_mutex); +		} +	} else { +		mutex_enter(&dkp->dk_pm_mutex); +		dkp->dk_pm_level = CMDK_SPINDLE_UNINIT; +		dkp->dk_pm_is_enabled = 0; +		mutex_exit(&dkp->dk_pm_mutex); +	} +} + +/* + * suspend routine, it will be run when get the command + * DDI_SUSPEND at detach(9E) from system power management + */ +static int +cmdksuspend(dev_info_t *dip) +{ +	struct cmdk	*dkp; +	int		instance; +	clock_t		count = 0; + +	instance = ddi_get_instance(dip); +	if (!(dkp = ddi_get_soft_state(cmdk_state, instance))) +		return (DDI_FAILURE); +	mutex_enter(&dkp->dk_mutex); +	if (dkp->dk_flag & CMDK_SUSPEND) { +		mutex_exit(&dkp->dk_mutex); +		return (DDI_SUCCESS); +	} +	dkp->dk_flag |= CMDK_SUSPEND; + +	/* need to wait a while */ +	while (dadk_getcmds(DKTP_DATA) != 0) { +		delay(drv_usectohz(1000000)); +		if (count > 60) { +			dkp->dk_flag &= ~CMDK_SUSPEND; +			cv_broadcast(&dkp->dk_suspend_cv); +			mutex_exit(&dkp->dk_mutex); +			return (DDI_FAILURE); +		} +		count++; +	} +	mutex_exit(&dkp->dk_mutex); +	return (DDI_SUCCESS); +} + +/* + * resume routine, it will be run when get the command + * DDI_RESUME at attach(9E) from system power management + */ +static int +cmdkresume(dev_info_t *dip) +{ +	struct cmdk	*dkp; +	int		instance; + +	instance = ddi_get_instance(dip); +	if (!(dkp = ddi_get_soft_state(cmdk_state, instance))) +		return (DDI_FAILURE); +	mutex_enter(&dkp->dk_mutex); +	if (!(dkp->dk_flag & CMDK_SUSPEND)) { +		mutex_exit(&dkp->dk_mutex); +		return (DDI_FAILURE); +	} +	dkp->dk_pm_level = CMDK_SPINDLE_ON; +	dkp->dk_flag &= ~CMDK_SUSPEND; +	cv_broadcast(&dkp->dk_suspend_cv); +	mutex_exit(&dkp->dk_mutex); +	return (DDI_SUCCESS); + +} + +/* + * power management entry point, it was used to + * change power management component. + * Actually, the real hard drive suspend/resume + * was handled in ata, so this function is not + * doing any real work other than verifying that + * the disk is idle. + */ +static int +cmdkpower(dev_info_t *dip, int component, int level) +{ +	struct cmdk	*dkp; +	int		instance; + +	instance = ddi_get_instance(dip); +	if (!(dkp = ddi_get_soft_state(cmdk_state, instance)) || +	    component != 0 || level > CMDK_SPINDLE_ON || +	    level < CMDK_SPINDLE_OFF) { +		return (DDI_FAILURE); +	} + +	mutex_enter(&dkp->dk_pm_mutex); +	if (dkp->dk_pm_is_enabled && dkp->dk_pm_level == level) { +		mutex_exit(&dkp->dk_pm_mutex); +		return (DDI_SUCCESS); +	} +	mutex_exit(&dkp->dk_pm_mutex); + +	if ((level == CMDK_SPINDLE_OFF) && +	    (dadk_getcmds(DKTP_DATA) != 0)) { +		return (DDI_FAILURE); +	} + +	mutex_enter(&dkp->dk_pm_mutex); +	dkp->dk_pm_level = level; +	mutex_exit(&dkp->dk_pm_mutex); +	return (DDI_SUCCESS); +} +  static int  cmdk_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,      char *name, caddr_t valuep, int *lengthp) @@ -677,6 +846,12 @@ cmdkioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp, int *rvalp)  	if (!(dkp = ddi_get_soft_state(cmdk_state, instance)))  		return (ENXIO); +	mutex_enter(&dkp->dk_mutex); +	while (dkp->dk_flag & CMDK_SUSPEND) { +		cv_wait(&dkp->dk_suspend_cv, &dkp->dk_mutex); +	} +	mutex_exit(&dkp->dk_mutex); +  	bzero(data, sizeof (data));  	switch (cmd) { @@ -873,6 +1048,10 @@ cmdkclose(dev_t dev, int flag, int otyp, cred_t *credp)  		return (ENXIO);  	} +	while (dkp->dk_flag & CMDK_SUSPEND) { +		cv_wait(&dkp->dk_suspend_cv, &dkp->dk_mutex); +	} +  	part = CMDKPART(dev);  	partbit = 1 << part; @@ -926,6 +1105,12 @@ cmdkopen(dev_t *dev_p, int flag, int otyp, cred_t *credp)  	if (otyp >= OTYPCNT)  		return (EINVAL); +	mutex_enter(&dkp->dk_mutex); +	while (dkp->dk_flag & CMDK_SUSPEND) { +		cv_wait(&dkp->dk_suspend_cv, &dkp->dk_mutex); +	} +	mutex_exit(&dkp->dk_mutex); +  	part = CMDKPART(dev);  	partbit = 1 << part;  	nodelay = (flag & (FNDELAY | FNONBLOCK)); @@ -1040,12 +1225,38 @@ cmdkmin(struct buf *bp)  static int  cmdkrw(dev_t dev, struct uio *uio, int flag)  { +	int 		instance; +	struct	cmdk	*dkp; + +	instance = CMDKUNIT(dev); +	if (!(dkp = ddi_get_soft_state(cmdk_state, instance))) +		return (ENXIO); + +	mutex_enter(&dkp->dk_mutex); +	while (dkp->dk_flag & CMDK_SUSPEND) { +		cv_wait(&dkp->dk_suspend_cv, &dkp->dk_mutex); +	} +	mutex_exit(&dkp->dk_mutex); +  	return (physio(cmdkstrategy, (struct buf *)0, dev, flag, cmdkmin, uio));  }  static int  cmdkarw(dev_t dev, struct aio_req *aio, int flag)  { +	int 		instance; +	struct	cmdk	*dkp; + +	instance = CMDKUNIT(dev); +	if (!(dkp = ddi_get_soft_state(cmdk_state, instance))) +		return (ENXIO); + +	mutex_enter(&dkp->dk_mutex); +	while (dkp->dk_flag & CMDK_SUSPEND) { +		cv_wait(&dkp->dk_suspend_cv, &dkp->dk_mutex); +	} +	mutex_exit(&dkp->dk_mutex); +  	return (aphysio(cmdkstrategy, anocancel, dev, flag, cmdkmin, aio));  } @@ -1070,6 +1281,12 @@ cmdkstrategy(struct buf *bp)  		return (0);  	} +	mutex_enter(&dkp->dk_mutex); +	while (dkp->dk_flag & CMDK_SUSPEND) { +		cv_wait(&dkp->dk_suspend_cv, &dkp->dk_mutex); +	} +	mutex_exit(&dkp->dk_mutex); +  	bp->b_flags &= ~(B_DONE|B_ERROR);  	bp->b_resid = 0;  	bp->av_back = NULL; @@ -1895,7 +2112,7 @@ cmdk_bbh_gethandle(opaque_t bbh_data, struct buf *bp)  		/* at least one bad sector in our section.  break it. */  		/* CASE 5: */  		if ((lastsec >= altp->bad_start) && -			    (lastsec <= altp->bad_end)) { +		    (lastsec <= altp->bad_end)) {  			ckp[idx+1].ck_seclen = lastsec - altp->bad_start + 1;  			ckp[idx].ck_seclen -= ckp[idx+1].ck_seclen;  			ckp[idx+1].ck_sector = altp->good_start; diff --git a/usr/src/uts/intel/io/dktp/hba/ghd/ghd_debug.c b/usr/src/uts/intel/io/dktp/hba/ghd/ghd_debug.c index 068dbd9f76..ae591ae1b8 100644 --- a/usr/src/uts/intel/io/dktp/hba/ghd/ghd_debug.c +++ b/usr/src/uts/intel/io/dktp/hba/ghd/ghd_debug.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2004 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -56,28 +56,29 @@ ghd_err(const char *fmt, ...)  }  #if defined(GHD_DEBUG) +#include <sys/promif.h>  #define	PRF	prom_printf  static void  ghd_dump_ccc(ccc_t *P)  {  	PRF("nextp 0x%p tmrp 0x%p label 0x%p &mutex 0x%p\n", -		P->ccc_nextp, P->ccc_tmrp, P->ccc_label, &P->ccc_activel_mutex); +	    P->ccc_nextp, P->ccc_tmrp, P->ccc_label, &P->ccc_activel_mutex);  	PRF("&activel 0x%p dip 0x%p iblock 0x%p\n", -		&P->ccc_activel, P->ccc_hba_dip, P->ccc_iblock); +	    &P->ccc_activel, P->ccc_hba_dip, P->ccc_iblock);  	PRF("softid 0x%p &hba_mutext 0x%p\n poll 0x%p\n", -		P->ccc_soft_id, &P->ccc_hba_mutex, &P->ccc_hba_pollmode); +	    P->ccc_soft_id, &P->ccc_hba_mutex, &P->ccc_hba_pollmode);  	PRF("&devs 0x%p &waitq_mutex 0x%p &waitq 0x%p\n", -		&P->ccc_devs, &P->ccc_waitq_mutex, &P->ccc_waitq); +	    &P->ccc_devs, &P->ccc_waitq_mutex, &P->ccc_waitq);  	PRF("waitq_freezetime 0x%p waitq_freezedelay %p\n", -		&P->ccc_waitq_freezetime, &P->ccc_waitq_freezedelay); +	    &P->ccc_waitq_freezetime, &P->ccc_waitq_freezedelay);  	PRF("dq softid 0x%p &dq_mutex 0x%p &doneq 0x%p\n", -		P->ccc_doneq_softid, &P->ccc_doneq_mutex, &P->ccc_doneq); +	    P->ccc_doneq_softid, &P->ccc_doneq_mutex, &P->ccc_doneq);  	PRF("handle 0x%p &ccballoc 0x%p\n", -		P->ccc_hba_handle, &P->ccc_ccballoc); +	    P->ccc_hba_handle, &P->ccc_ccballoc);  	PRF("hba_reset_notify_callback 0x%p notify_list 0x%p mutex 0x%p\n", -		P->ccc_hba_reset_notify_callback, &P->ccc_reset_notify_list, -		&P->ccc_reset_notify_mutex); +	    P->ccc_hba_reset_notify_callback, &P->ccc_reset_notify_list, +	    &P->ccc_reset_notify_mutex);  } diff --git a/usr/src/uts/intel/io/pci/pci_pci.c b/usr/src/uts/intel/io/pci/pci_pci.c index b6dbe7f1b9..753c04d8f8 100644 --- a/usr/src/uts/intel/io/pci/pci_pci.c +++ b/usr/src/uts/intel/io/pci/pci_pci.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -319,7 +319,7 @@ ppb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)  		    DDI_FM_EREPORT_CAPABLE))  			pci_ereport_setup(devi);  		if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE) -		    ddi_fm_handler_register(devi, ppb_fm_callback, NULL); +			ddi_fm_handler_register(devi, ppb_fm_callback, NULL);  		if (pci_config_setup(devi, &config_handle) != DDI_SUCCESS) {  			if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE) @@ -348,7 +348,8 @@ ppb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)  		 * to this bus.  		 */  		if (pcihp_init(devi) != DDI_SUCCESS) -		    cmn_err(CE_WARN, "pci: Failed to setup hotplug framework"); +			cmn_err(CE_WARN, +			    "pci: Failed to setup hotplug framework");  		ddi_report_dev(devi);  		return (DDI_SUCCESS); @@ -419,7 +420,7 @@ ppb_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,  	pdip = (dev_info_t *)DEVI(dip)->devi_parent;  	return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map)(pdip, -			rdip, mp, offset, len, vaddrp)); +	    rdip, mp, offset, len, vaddrp));  }  /*ARGSUSED*/ @@ -432,6 +433,7 @@ ppb_ctlops(dev_info_t *dip, dev_info_t *rdip,  	int	rn;  	int	totreg;  	ppb_devstate_t *ppb; +	struct attachspec *asp;  	switch (ctlop) {  	case DDI_CTLOPS_REPORTDEV: @@ -459,6 +461,22 @@ ppb_ctlops(dev_info_t *dip, dev_info_t *rdip,  			return (DDI_FAILURE);  		break; +	/* X86 systems support PME wakeup from suspend */ +	case DDI_CTLOPS_ATTACH: +		asp = (struct attachspec *)arg; +		if (asp->cmd == DDI_RESUME && asp->when == DDI_PRE) +			if (pci_pre_resume(rdip) != DDI_SUCCESS) +				return (DDI_FAILURE); +		return (ddi_ctlops(dip, rdip, ctlop, arg, result)); + + +	case DDI_CTLOPS_DETACH: +		asp = (struct attachspec *)arg; +		if (asp->cmd == DDI_SUSPEND && asp->when == DDI_POST) +			if (pci_post_suspend(rdip) != DDI_SUCCESS) +				return (DDI_FAILURE); +		return (ddi_ctlops(dip, rdip, ctlop, arg, result)); +  	case DDI_CTLOPS_PEEK:  	case DDI_CTLOPS_POKE:  		ppb = ddi_get_soft_state(ppb_state, ddi_get_instance(dip)); @@ -474,8 +492,8 @@ ppb_ctlops(dev_info_t *dip, dev_info_t *rdip,  	*(int *)result = 0;  	if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, -		DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "reg", -		(caddr_t)&drv_regp, ®len) != DDI_SUCCESS) +	    DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "reg", +	    (caddr_t)&drv_regp, ®len) != DDI_SUCCESS)  		return (DDI_FAILURE);  	totreg = reglen / sizeof (pci_regspec_t); @@ -596,8 +614,8 @@ ppb_initchild(dev_info_t *child)  	}  	/* transfer select properties from PROM to kernel */ -	if (ddi_getprop(DDI_DEV_T_NONE, child, DDI_PROP_DONTPASS, "interrupts", -		-1) != -1) { +	if (ddi_getprop(DDI_DEV_T_NONE, child, DDI_PROP_DONTPASS, +	    "interrupts", -1) != -1) {  		pdptr = kmem_zalloc((sizeof (struct ddi_parent_private_data) +  		    sizeof (struct intrspec)), KM_SLEEP);  		pdptr->par_intr = (struct intrspec *)(pdptr + 1); @@ -660,20 +678,20 @@ ppb_save_config_regs(ppb_devstate_t *ppb_p)  	ddi_acc_handle_t config_handle;  	for (i = 0, dip = ddi_get_child(ppb_p->dip); dip != NULL; -			i++, dip = ddi_get_next_sibling(dip)) { +	    i++, dip = ddi_get_next_sibling(dip)) {  		if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {  			cmn_err(CE_WARN, "%s%d: can't config space for %s%d\n", -				ddi_driver_name(ppb_p->dip), -				ddi_get_instance(ppb_p->dip), -				ddi_driver_name(dip), -				ddi_get_instance(dip)); +			    ddi_driver_name(ppb_p->dip), +			    ddi_get_instance(ppb_p->dip), +			    ddi_driver_name(dip), +			    ddi_get_instance(dip));  			continue;  		}  		ppb_p->config_state[i].dip = dip;  		ppb_p->config_state[i].command = -			pci_config_get16(config_handle, PCI_CONF_COMM); +		    pci_config_get16(config_handle, PCI_CONF_COMM);  		pci_config_teardown(&config_handle);  	}  	ppb_p->config_state_index = i; @@ -701,14 +719,14 @@ ppb_restore_config_regs(ppb_devstate_t *ppb_p)  		dip = ppb_p->config_state[i].dip;  		if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {  			cmn_err(CE_WARN, "%s%d: can't config space for %s%d\n", -				ddi_driver_name(ppb_p->dip), -				ddi_get_instance(ppb_p->dip), -				ddi_driver_name(dip), -				ddi_get_instance(dip)); +			    ddi_driver_name(ppb_p->dip), +			    ddi_get_instance(ppb_p->dip), +			    ddi_driver_name(dip), +			    ddi_get_instance(dip));  			continue;  		}  		pci_config_put16(config_handle, PCI_CONF_COMM, -				ppb_p->config_state[i].command); +		    ppb_p->config_state[i].command);  		pci_config_teardown(&config_handle);  	}  } diff --git a/usr/src/uts/intel/io/vgatext/vgatext.c b/usr/src/uts/intel/io/vgatext/vgatext.c index 7835b63ecd..4e85cd7fd9 100644 --- a/usr/src/uts/intel/io/vgatext/vgatext.c +++ b/usr/src/uts/intel/io/vgatext/vgatext.c @@ -86,6 +86,15 @@  #define	VGA_MMAP_FB_BASE	VGA_MEM_ADDR +/* + * This variable allows for this driver to suspend even if it + * shouldn't.  Note that by setting it, the framebuffer will probably + * not come back.  So use it with a serial console, or with serial + * line debugging (say, for example, if this driver is being modified + * to support _some_ hardware doing suspend and resume). + */ +int vgatext_force_suspend = 0; +  static int vgatext_open(dev_t *, int, int, cred_t *);  static int vgatext_close(dev_t, int, int, cred_t *);  static int vgatext_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); @@ -271,7 +280,7 @@ _init(void)  	e = mod_install(&modlinkage);  	if (e) { -	    ddi_soft_state_fini(&vgatext_softc_head); +		ddi_soft_state_fini(&vgatext_softc_head);  	}  	return (e);  } @@ -282,7 +291,7 @@ _fini(void)  	int e;  	if ((e = mod_remove(&modlinkage)) != 0) -	    return (e); +		return (e);  	ddi_soft_state_fini(&vgatext_softc_head); @@ -334,7 +343,7 @@ vgatext_check_for_console(dev_info_t *devi, struct vgatext_softc *softc,  	if (pci_config_setup(devi, &pci_conf) != DDI_SUCCESS) {  		cmn_err(CE_WARN, -			MYNAME ": can't get PCI conf handle"); +		    MYNAME ": can't get PCI conf handle");  		return;  	} @@ -410,12 +419,18 @@ vgatext_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)  	switch (cmd) {  	case DDI_ATTACH: -	    break; +		break;  	case DDI_RESUME: -	    return (DDI_SUCCESS); +		/* +		 * Though vgatext doesn't really know how to resume +		 * on a generic framebuffer, we should succeed, as +		 * it is far better to have no console, than potentiall +		 * have no machine. +		 */ +		return (DDI_SUCCESS);  	default: -	    return (DDI_FAILURE); +		return (DDI_FAILURE);  	}  	/* DDI_ATTACH */ @@ -436,7 +451,7 @@ vgatext_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)  	softc->polledio.cursor = vgatext_polled_cursor;  	error = ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(devi), -		DDI_PROP_DONTPASS, "device_type", &parent_type); +	    DDI_PROP_DONTPASS, "device_type", &parent_type);  	if (error != DDI_SUCCESS) {  		cmn_err(CE_WARN, MYNAME ": can't determine parent type.");  		goto fail; @@ -444,47 +459,47 @@ vgatext_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)  	if (STREQ(parent_type, "isa") || STREQ(parent_type, "eisa")) {  		reg_rnumber = vgatext_get_isa_reg_index(devi, 1, VGA_REG_ADDR, -			®_offset); +		    ®_offset);  		if (reg_rnumber < 0) {  			cmn_err(CE_WARN, -				MYNAME ": can't find reg entry for registers"); +			    MYNAME ": can't find reg entry for registers");  			error = DDI_FAILURE;  			goto fail;  		}  		softc->fb_regno = vgatext_get_isa_reg_index(devi, 0, -			VGA_MEM_ADDR, &mem_offset); +		    VGA_MEM_ADDR, &mem_offset);  		if (softc->fb_regno < 0) {  			cmn_err(CE_WARN, -				MYNAME ": can't find reg entry for memory"); +			    MYNAME ": can't find reg entry for memory");  			error = DDI_FAILURE;  			goto fail;  		}  	} else if (STREQ(parent_type, "pci") || STREQ(parent_type, "pciex")) {  		pci_pcie_bus = 1;  		reg_rnumber = vgatext_get_pci_reg_index(devi, -			PCI_REG_ADDR_M|PCI_REG_REL_M, -			PCI_ADDR_IO|PCI_RELOCAT_B, VGA_REG_ADDR, -			®_offset); +		    PCI_REG_ADDR_M|PCI_REG_REL_M, +		    PCI_ADDR_IO|PCI_RELOCAT_B, VGA_REG_ADDR, +		    ®_offset);  		if (reg_rnumber < 0) {  			cmn_err(CE_WARN, -				MYNAME ": can't find reg entry for registers"); +			    MYNAME ": can't find reg entry for registers");  			error = DDI_FAILURE;  			goto fail;  		}  		softc->fb_regno = vgatext_get_pci_reg_index(devi, -			PCI_REG_ADDR_M|PCI_REG_REL_M, -			PCI_ADDR_MEM32|PCI_RELOCAT_B, VGA_MEM_ADDR, -			&mem_offset); +		    PCI_REG_ADDR_M|PCI_REG_REL_M, +		    PCI_ADDR_MEM32|PCI_RELOCAT_B, VGA_MEM_ADDR, +		    &mem_offset);  		if (softc->fb_regno < 0) {  			cmn_err(CE_WARN, -				MYNAME ": can't find reg entry for memory"); +			    MYNAME ": can't find reg entry for memory");  			error = DDI_FAILURE;  			goto fail;  		}  		agpm = 1;	/* should have AGP master support */  	} else {  		cmn_err(CE_WARN, MYNAME ": unknown parent type \"%s\".", -			parent_type); +		    parent_type);  		error = DDI_FAILURE;  		goto fail;  	} @@ -492,8 +507,8 @@ vgatext_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)  	parent_type = NULL;  	error = ddi_regs_map_setup(devi, reg_rnumber, -		(caddr_t *)&softc->regs.addr, reg_offset, VGA_REG_SIZE, -		&dev_attr, &softc->regs.handle); +	    (caddr_t *)&softc->regs.addr, reg_offset, VGA_REG_SIZE, +	    &dev_attr, &softc->regs.handle);  	if (error != DDI_SUCCESS)  		goto fail;  	softc->regs.mapped = B_TRUE; @@ -501,9 +516,9 @@ vgatext_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)  	softc->fb_size = VGA_MEM_SIZE;  	error = ddi_regs_map_setup(devi, softc->fb_regno, -		(caddr_t *)&softc->fb.addr, -		mem_offset, softc->fb_size, -		&dev_attr, &softc->fb.handle); +	    (caddr_t *)&softc->fb.addr, +	    mem_offset, softc->fb_size, +	    &dev_attr, &softc->fb.handle);  	if (error != DDI_SUCCESS)  		goto fail;  	softc->fb.mapped = B_TRUE; @@ -527,7 +542,7 @@ vgatext_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)  		goto fail;  	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), -		DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) { +	    DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) {  		if (strcmp(cons, "graphics") == 0) {  			happyface_boot = 1;  			vgatext_silent = 1; @@ -589,6 +604,28 @@ vgatext_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)  		(void) ddi_soft_state_free(vgatext_softc_head, instance);  		return (DDI_SUCCESS); +	case DDI_SUSPEND: +		/* +		 * This is a generic VGA file, and therefore, cannot +		 * understand how to deal with suspend and resume on +		 * a generic interface.  So we fail any attempt to +		 * suspend.  At some point in the future, we might use +		 * this as an entrypoint for display drivers and this +		 * assumption may change. +		 * +		 * However, from a platform development perspective, +		 * it is important that this driver suspend if a +		 * developer is using a serial console and/or working +		 * on a framebuffer driver that will support suspend +		 * and resume.  Therefore, we have this module tunable +		 * (purposely using a long name) that will allow for +		 * suspend it it is set.  Otherwise we fail. +		 */ +		if (vgatext_force_suspend != 0) +			return (DDI_SUCCESS); +		else +			return (DDI_FAILURE); +  	default:  		cmn_err(CE_WARN, "vgatext_detach: unknown cmd 0x%x\n", cmd);  		return (DDI_FAILURE); @@ -676,59 +713,59 @@ do_gfx_ioctl(int cmd, intptr_t data, int mode, struct vgatext_softc *softc)  	case VIS_DEVINIT: -	    if (!(mode & FKIOCTL)) { -		    cmn_err(CE_CONT, kernel_only, "VIS_DEVINIT"); -		    return (ENXIO); -	    } +		if (!(mode & FKIOCTL)) { +			cmn_err(CE_CONT, kernel_only, "VIS_DEVINIT"); +			return (ENXIO); +		} -	    err = vgatext_devinit(softc, (struct vis_devinit *)data); -	    if (err != 0) { -		    cmn_err(CE_WARN, -			"vgatext_ioctl:  could not initialize console"); -		    return (err); -	    } -	    break; +		err = vgatext_devinit(softc, (struct vis_devinit *)data); +		if (err != 0) { +			cmn_err(CE_WARN, +			    "vgatext_ioctl:  could not initialize console"); +			return (err); +		} +		break;  	case VIS_CONSCOPY:	/* move */ -	{ -	    struct vis_conscopy pma; +		{ +		struct vis_conscopy pma; -	    if (ddi_copyin((void *)data, &pma, -		sizeof (struct vis_conscopy), mode)) -		    return (EFAULT); +		if (ddi_copyin((void *)data, &pma, +		    sizeof (struct vis_conscopy), mode)) +			return (EFAULT); -	    vgatext_cons_copy(softc, &pma); -	    break; -	} +		vgatext_cons_copy(softc, &pma); +		break; +		}  	case VIS_CONSDISPLAY:	/* display */ -	{ -	    struct vis_consdisplay display_request; +		{ +		struct vis_consdisplay display_request; -	    if (ddi_copyin((void *)data, &display_request, -		sizeof (display_request), mode)) -		    return (EFAULT); +		if (ddi_copyin((void *)data, &display_request, +		    sizeof (display_request), mode)) +			return (EFAULT); -	    vgatext_cons_display(softc, &display_request); -	    break; -	} +		vgatext_cons_display(softc, &display_request); +		break; +		}  	case VIS_CONSCURSOR: -	{ -	    struct vis_conscursor cursor_request; +		{ +		struct vis_conscursor cursor_request; -	    if (ddi_copyin((void *)data, &cursor_request, -		sizeof (cursor_request), mode)) -		    return (EFAULT); +		if (ddi_copyin((void *)data, &cursor_request, +		    sizeof (cursor_request), mode)) +			return (EFAULT); -	    vgatext_cons_cursor(softc, &cursor_request); +		vgatext_cons_cursor(softc, &cursor_request); -	    if (cursor_request.action == VIS_GET_CURSOR && -		ddi_copyout(&cursor_request, (void *)data, -		sizeof (cursor_request), mode)) -		    return (EFAULT); -	    break; -	} +		if (cursor_request.action == VIS_GET_CURSOR && +		    ddi_copyout(&cursor_request, (void *)data, +		    sizeof (cursor_request), mode)) +			return (EFAULT); +		break; +		}  	case VIS_GETCMAP:  	case VIS_PUTCMAP: @@ -807,7 +844,7 @@ vgatext_kdsetmode(struct vgatext_softc *softc, int mode)  		softc->current_base = softc->text_base;  		if (softc->cursor.visible) {  			vgatext_set_cursor(softc, -				softc->cursor.row, softc->cursor.col); +			    softc->cursor.row, softc->cursor.col);  		}  		vgatext_restore_colormap(softc);  		break; @@ -852,7 +889,7 @@ vgatext_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len,  	}  	if (!(off >= VGA_MMAP_FB_BASE && -		off < VGA_MMAP_FB_BASE + softc->fb_size)) { +	    off < VGA_MMAP_FB_BASE + softc->fb_size)) {  		cmn_err(CE_WARN, "vgatext: Can't map offset 0x%llx", off);  		return (-1);  	} @@ -863,8 +900,8 @@ vgatext_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len,  		length = len;  	if ((err = devmap_devmem_setup(dhp, softc->devi, NULL, softc->fb_regno, -					off - VGA_MMAP_FB_BASE, -					length, PROT_ALL, 0, &dev_attr)) < 0) { +	    off - VGA_MMAP_FB_BASE, +	    length, PROT_ALL, 0, &dev_attr)) < 0) {  		return (err);  	} @@ -924,10 +961,10 @@ vgatext_cons_display(struct vgatext_softc *softc, struct vis_consdisplay *da)  	 * system startup graphics.  	 */  	attr = (solaris_color_to_pc_color[da->bg_color & 0xf] << 4) -		| solaris_color_to_pc_color[da->fg_color & 0xf]; +	    | solaris_color_to_pc_color[da->fg_color & 0xf];  	string = da->data;  	addr = (struct cgatext *)softc->current_base -		+  (da->row * TEXT_COLS + da->col); +	    +  (da->row * TEXT_COLS + da->col);  	for (i = 0; i < da->width; i++) {  		addr->ch = string[i];  		addr->attr = attr; @@ -1130,20 +1167,20 @@ vgatext_set_text(struct vgatext_softc *softc)  	/* set sequencer registers */  	vga_set_seq(&softc->regs, VGA_SEQ_RST_SYN, -		(vga_get_seq(&softc->regs, VGA_SEQ_RST_SYN) & -		~VGA_SEQ_RST_SYN_NO_SYNC_RESET)); +	    (vga_get_seq(&softc->regs, VGA_SEQ_RST_SYN) & +	    ~VGA_SEQ_RST_SYN_NO_SYNC_RESET));  	for (i = 1; i < NUM_SEQ_REG; i++) {  		vga_set_seq(&softc->regs, i, VGA_SEQ_TEXT[i]);  	}  	vga_set_seq(&softc->regs, VGA_SEQ_RST_SYN, -		(vga_get_seq(&softc->regs, VGA_SEQ_RST_SYN) | -		VGA_SEQ_RST_SYN_NO_ASYNC_RESET | -		VGA_SEQ_RST_SYN_NO_SYNC_RESET)); +	    (vga_get_seq(&softc->regs, VGA_SEQ_RST_SYN) | +	    VGA_SEQ_RST_SYN_NO_ASYNC_RESET | +	    VGA_SEQ_RST_SYN_NO_SYNC_RESET));  	/* set crt controller registers */  	vga_set_crtc(&softc->regs, VGA_CRTC_VRE, -		(vga_get_crtc(&softc->regs, VGA_CRTC_VRE) & -		~VGA_CRTC_VRE_LOCK)); +	    (vga_get_crtc(&softc->regs, VGA_CRTC_VRE) & +	    ~VGA_CRTC_VRE_LOCK));  	for (i = 0; i < NUM_CRTC_REG; i++) {  		vga_set_crtc(&softc->regs, i, VGA_CRTC_TEXT[i]);  	} @@ -1161,8 +1198,8 @@ vgatext_set_text(struct vgatext_softc *softc)  	/* set palette */  	for (i = 0; i < VGA_TEXT_CMAP_ENTRIES; i++) {  		vga_put_cmap(&softc->regs, i, VGA_TEXT_PALETTES[i][0] << 2, -			VGA_TEXT_PALETTES[i][1] << 2, -			VGA_TEXT_PALETTES[i][2] << 2); +		    VGA_TEXT_PALETTES[i][1] << 2, +		    VGA_TEXT_PALETTES[i][2] << 2);  	}  	for (i = VGA_TEXT_CMAP_ENTRIES; i < VGA8_CMAP_ENTRIES; i++) {  		vga_put_cmap(&softc->regs, i, 0, 0, 0); @@ -1185,10 +1222,10 @@ vgatext_init(struct vgatext_softc *softc)  	vga_set_atr(&softc->regs, VGA_ATR_MODE, atr_mode);  #if	defined(USE_BORDERS)  	vga_set_atr(&softc->regs, VGA_ATR_BDR_CLR, -		vga_get_atr(&softc->regs, VGA_BRIGHT_WHITE)); +	    vga_get_atr(&softc->regs, VGA_BRIGHT_WHITE));  #else  	vga_set_atr(&softc->regs, VGA_ATR_BDR_CLR, -		vga_get_atr(&softc->regs, VGA_BLACK)); +	    vga_get_atr(&softc->regs, VGA_BLACK));  #endif  	vgatext_setfont(softc);	/* need selectable font? */  } @@ -1198,7 +1235,7 @@ static void  vgatext_init_graphics(struct vgatext_softc *softc)  {  	vga_set_atr(&softc->regs, VGA_ATR_BDR_CLR, -		vga_get_atr(&softc->regs, VGA_BLACK)); +	    vga_get_atr(&softc->regs, VGA_BLACK));  }  #endif @@ -1301,9 +1338,9 @@ vgatext_save_colormap(struct vgatext_softc *softc)  	}  	for (i = 0; i < VGA8_CMAP_ENTRIES; i++) {  		vga_get_cmap(&softc->regs, i, -			&softc->colormap[i].red, -			&softc->colormap[i].green, -			&softc->colormap[i].blue); +		    &softc->colormap[i].red, +		    &softc->colormap[i].green, +		    &softc->colormap[i].blue);  	}  } @@ -1317,9 +1354,9 @@ vgatext_restore_colormap(struct vgatext_softc *softc)  	}  	for (i = 0; i < VGA8_CMAP_ENTRIES; i++) {  		vga_put_cmap(&softc->regs, i, -			softc->colormap[i].red, -			softc->colormap[i].green, -			softc->colormap[i].blue); +		    softc->colormap[i].red, +		    softc->colormap[i].green, +		    softc->colormap[i].blue);  	}  } @@ -1354,7 +1391,7 @@ vgatext_get_pci_reg_index(  	pci_regspec_t	*reg;  	if (ddi_getlongprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, -		"reg", (caddr_t)®, &length) != DDI_PROP_SUCCESS) { +	    "reg", (caddr_t)®, &length) != DDI_PROP_SUCCESS) {  		return (-1);  	} @@ -1413,7 +1450,7 @@ vgatext_get_isa_reg_index(  	struct regspec	*reg;  	if (ddi_getlongprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, -		"reg", (caddr_t)®, &length) != DDI_PROP_SUCCESS) { +	    "reg", (caddr_t)®, &length) != DDI_PROP_SUCCESS) {  		return (-1);  	} diff --git a/usr/src/uts/intel/os/cpr_intel.c b/usr/src/uts/intel/os/cpr_intel.c new file mode 100644 index 0000000000..b34041386b --- /dev/null +++ b/usr/src/uts/intel/os/cpr_intel.c @@ -0,0 +1,75 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident	"%Z%%M%	%I%	%E% SMI" + +/* + * cpr functions for supported sparc platforms + */ +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/cpr.h> +#include <sys/kmem.h> +#include <sys/errno.h> + +/* + * setup the original and new sets of property names/values + * Not relevant to S3, which is all we support for now. + */ +/*ARGSUSED*/ +int +cpr_default_setup(int alloc) +{ +	return (0); +} + +void +cpr_send_notice(void) +{ +	static char cstr[] = "\014" "\033[1P" "\033[18;21H"; + +	prom_printf(cstr); +	prom_printf("Saving System State. Please Wait... "); +} + +void +cpr_spinning_bar(void) +{ +	static char *spin_strings[] = { "|\b", "/\b", "-\b", "\\\b" }; +	static int idx; + +	prom_printf(spin_strings[idx]); +	if (++idx == 4) +		idx = 0; +} + +void +cpr_resume_notice(void) +{ +	static char cstr[] = "\014" "\033[1P" "\033[18;21H"; + +	prom_printf(cstr); +	prom_printf("Restoring System State. Please Wait... "); +} diff --git a/usr/src/uts/intel/os/name_to_major b/usr/src/uts/intel/os/name_to_major index 9d983ec052..28810d57b0 100644 --- a/usr/src/uts/intel/os/name_to_major +++ b/usr/src/uts/intel/os/name_to_major @@ -127,6 +127,8 @@ evtchn 197  xdb 199  domcaps 200  balloon 201 +acpippm 202 +srn 203  did 239  lx_ptm 240  lx_systrace 241 diff --git a/usr/src/uts/intel/promif/prom_env.c b/usr/src/uts/intel/promif/prom_env.c index 4b43f678ef..73b2a08af6 100644 --- a/usr/src/uts/intel/promif/prom_env.c +++ b/usr/src/uts/intel/promif/prom_env.c @@ -2,9 +2,8 @@   * CDDL HEADER START   *   * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License").  You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License.   *   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE   * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@   *   * CDDL HEADER END   */ +  /* - * Copyright 2004 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -47,6 +47,7 @@ static promif_owrap_t nullwrapper =  static promif_owrap_t *wrapper = &nullwrapper;  static promif_owrap_t pmwrapper; +static promif_owrap_t *saved_wrapper;  promif_owrap_t  *promif_preout(void) @@ -69,3 +70,17 @@ prom_set_outfuncs(void (*pref)(void), void (*postf)(void))  	pmwrapper.postout = postf;  	wrapper = &pmwrapper;  } + +void +prom_suspend_prepost(void) +{ +	saved_wrapper = wrapper; +	wrapper = &nullwrapper; +} + +void +prom_resume_prepost(void) +{ +	wrapper = saved_wrapper; +	saved_wrapper = NULL; +} diff --git a/usr/src/uts/intel/srn/Makefile b/usr/src/uts/intel/srn/Makefile new file mode 100755 index 0000000000..8146241688 --- /dev/null +++ b/usr/src/uts/intel/srn/Makefile @@ -0,0 +1,84 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# uts/intel/srn/Makefile +# +# Copyright 2007 Sun Microsystems, Inc.  All rights reserved. +# Use is subject to license terms. +# +# ident	"%Z%%M%	%I%	%E% SMI" +# +#	This makefile drives the production of the srn driver +# +#	intel architecture dependent +# + +# +#	Path to the base of the uts directory tree (usually /usr/src/uts). +# +UTSBASE	= ../.. + +# +#	Define the module and object file sets. +# +MODULE		= srn +OBJECTS		= $(SRN_OBJS:%=$(OBJS_DIR)/%) +LINTS		= $(SRN_OBJS:%.o=$(LINTS_DIR)/%.ln) +ROOTMODULE	= $(ROOT_DRV_DIR)/$(MODULE) +CONF_SRCDIR	= $(UTSBASE)/common/io + +# +#	Include common rules. +# +include $(UTSBASE)/intel/Makefile.intel + +# +#	Define targets +# +ALL_TARGET	= $(BINARY) $(SRC_CONFILE) +LINT_TARGET	= $(MODULE).lint +INSTALL_TARGET	= $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE) + +# +#	Default build targets. +# +.KEEP_STATE: + +def:		$(DEF_DEPS) + +all:		$(ALL_DEPS) + +clean:		$(CLEAN_DEPS) + +clobber:	$(CLOBBER_DEPS) + +lint:		$(LINT_DEPS) + +modlintlib:	$(MODLINTLIB_DEPS) + +clean.lint:	$(CLEAN_LINT_DEPS) + +install:	$(INSTALL_DEPS) + +# +#	Include common targets. +# +include $(UTSBASE)/intel/Makefile.targ diff --git a/usr/src/uts/intel/sys/acpica.h b/usr/src/uts/intel/sys/acpica.h index b760afcb97..40e830fd05 100644 --- a/usr/src/uts/intel/sys/acpica.h +++ b/usr/src/uts/intel/sys/acpica.h @@ -128,6 +128,8 @@ extern ACPI_STATUS acpica_get_handle(dev_info_t *, ACPI_HANDLE *);  extern ACPI_STATUS acpica_eval_int(ACPI_HANDLE, char *, int *);  extern void acpica_map_cpu(processorid_t, MADT_PROCESSOR_APIC *);  extern void acpica_build_processor_map(); +extern void acpica_ddi_save_resources(dev_info_t *); +extern void acpica_ddi_restore_resources(dev_info_t *);  #ifdef __cplusplus  } diff --git a/usr/src/uts/intel/sys/promif.h b/usr/src/uts/intel/sys/promif.h index 20ce5c2db1..ee7e138f1e 100644 --- a/usr/src/uts/intel/sys/promif.h +++ b/usr/src/uts/intel/sys/promif.h @@ -2,9 +2,8 @@   * CDDL HEADER START   *   * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License").  You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License.   *   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE   * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2005 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -219,6 +218,9 @@ typedef struct promif_owrap {  	void (*postout)(void);  } promif_owrap_t; +extern	void		prom_suspend_prepost(void); +extern	void		prom_resume_prepost(void); +  /*   * WAN boot key storage interface   */ | 
