staticint zpodd_poweroff_delay = 30; /* 30 seconds for power off delay */
module_param(zpodd_poweroff_delay, int, 0644);
MODULE_PARM_DESC(zpodd_poweroff_delay, "Poweroff delay for ZPODD in seconds");
/* The following fields are synchronized by PM core. */ bool from_notify; /* resumed as a result of
* acpi wake notification */ bool zp_ready; /* ZP ready state */ unsignedlong last_ready; /* last ZP ready timestamp */ bool zp_sampled; /* ZP ready state sampled */ bool powered_off; /* ODD is powered off
* during suspend */
};
/* Test if ODD is zero power ready by sense code */ staticbool zpready(struct ata_device *dev)
{
u8 sense_key, *sense_buf; unsignedint ret, asc, ascq, add_len; struct zpodd *zpodd = dev->zpodd;
ret = atapi_eh_tur(dev, &sense_key);
if (!ret || sense_key != NOT_READY) returnfalse;
sense_buf = dev->sector_buf;
ret = atapi_eh_request_sense(dev, sense_buf, sense_key); if (ret) returnfalse;
/* sense valid */ if ((sense_buf[0] & 0x7f) != 0x70) returnfalse;
add_len = sense_buf[7]; /* has asc and ascq */ if (add_len < 6) returnfalse;
asc = sense_buf[12];
ascq = sense_buf[13];
if (zpodd->mech_type == ODD_MECH_TYPE_SLOT) /* no media inside */ return asc == 0x3a; else /* no media inside and door closed */ return asc == 0x3a && ascq == 0x01;
}
/* * Update the zpodd->zp_ready field. This field will only be set * if the ODD has stayed in ZP ready state for zpodd_poweroff_delay * time, and will be used to decide if power off is allowed. If it * is set, it will be cleared during resume from powered off state.
*/ void zpodd_on_suspend(struct ata_device *dev)
{ struct zpodd *zpodd = dev->zpodd; unsignedlong expires;
/* * Enable runtime wake capability through ACPI and set the powered_off flag, * this flag will be used during resume to decide what operations are needed * to take. * * Also, media poll needs to be silenced, so that it doesn't bring the ODD * back to full power state every few seconds.
*/ void zpodd_enable_run_wake(struct ata_device *dev)
{ struct zpodd *zpodd = dev->zpodd;
/* Disable runtime wake capability if it is enabled */ void zpodd_disable_run_wake(struct ata_device *dev)
{ struct zpodd *zpodd = dev->zpodd;
if (zpodd->powered_off)
acpi_pm_set_device_wakeup(&dev->tdev, false);
}
/* * Post power on processing after the ODD has been recovered. If the * ODD wasn't powered off during suspend, it doesn't do anything. * * For drawer type ODD, if it is powered on due to user pressed the * eject button, the tray needs to be ejected. This can only be done * after the ODD has been recovered, i.e. link is initialized and * device is able to process NON_DATA PIO command, as eject needs to * send command for the ODD to process. * * The from_notify flag set in wake notification handler function * zpodd_wake_dev represents if power on is due to user's action. * * For both types of ODD, several fields need to be reset.
*/ void zpodd_post_poweron(struct ata_device *dev)
{ struct zpodd *zpodd = dev->zpodd;
if (!zpodd->powered_off) return;
zpodd->powered_off = false;
if (zpodd->from_notify) {
zpodd->from_notify = false; if (zpodd->mech_type == ODD_MECH_TYPE_DRAWER)
eject_tray(dev);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.