summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/intel')
-rw-r--r--usr/src/uts/intel/Makefile.files3
-rw-r--r--usr/src/uts/intel/Makefile.intel.shared1
-rw-r--r--usr/src/uts/intel/ia32/ml/modstubs.s2
-rw-r--r--usr/src/uts/intel/io/acpica/acpica.c211
-rw-r--r--usr/src/uts/intel/io/agpgart/amd64_gart.c24
-rw-r--r--usr/src/uts/intel/io/dktp/controller/ata/ata_cmd.h5
-rw-r--r--usr/src/uts/intel/io/dktp/controller/ata/ata_common.c632
-rw-r--r--usr/src/uts/intel/io/dktp/controller/ata/ata_common.h15
-rw-r--r--usr/src/uts/intel/io/dktp/dcdev/dadk.c162
-rw-r--r--usr/src/uts/intel/io/dktp/disk/cmdk.c225
-rw-r--r--usr/src/uts/intel/io/dktp/hba/ghd/ghd_debug.c21
-rw-r--r--usr/src/uts/intel/io/pci/pci_pci.c56
-rw-r--r--usr/src/uts/intel/io/vgatext/vgatext.c219
-rw-r--r--usr/src/uts/intel/os/cpr_intel.c75
-rw-r--r--usr/src/uts/intel/os/name_to_major2
-rw-r--r--usr/src/uts/intel/promif/prom_env.c23
-rwxr-xr-xusr/src/uts/intel/srn/Makefile84
-rw-r--r--usr/src/uts/intel/sys/acpica.h2
-rw-r--r--usr/src/uts/intel/sys/promif.h10
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, &regsize);
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, &regsize);
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, &regsize);
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, &reglen) != DDI_SUCCESS)
+ DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "reg",
+ (caddr_t)&drv_regp, &reglen) != 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,
- &reg_offset);
+ &reg_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,
- &reg_offset);
+ PCI_REG_ADDR_M|PCI_REG_REL_M,
+ PCI_ADDR_IO|PCI_RELOCAT_B, VGA_REG_ADDR,
+ &reg_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)&reg, &length) != DDI_PROP_SUCCESS) {
+ "reg", (caddr_t)&reg, &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)&reg, &length) != DDI_PROP_SUCCESS) {
+ "reg", (caddr_t)&reg, &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
*/