// SPDX-License-Identifier: GPL-2.0 #include <linux/libata.h> #include <linux/cdrom.h> #include <linux/pm_runtime.h> #include <linux/module.h> #include <linux/pm_qos.h> #include <scsi/scsi_device.h> #include "libata.h" static int zpodd_poweroff_delay = …; /* 30 seconds for power off delay */ module_param(zpodd_poweroff_delay, int, 0644); MODULE_PARM_DESC(…) …; enum odd_mech_type { … }; struct zpodd { … }; static int eject_tray(struct ata_device *dev) { … } /* Per the spec, only slot type and drawer type ODD can be supported */ static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev) { … } /* Test if ODD is zero power ready by sense code */ static bool zpready(struct ata_device *dev) { … } /* * 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) { … } bool zpodd_zpready(struct ata_device *dev) { … } /* * 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) { … } /* Disable runtime wake capability if it is enabled */ void zpodd_disable_run_wake(struct ata_device *dev) { … } /* * 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) { … } static void zpodd_wake_dev(acpi_handle handle, u32 event, void *context) { … } static void ata_acpi_add_pm_notifier(struct ata_device *dev) { … } static void ata_acpi_remove_pm_notifier(struct ata_device *dev) { … } void zpodd_init(struct ata_device *dev) { … } void zpodd_exit(struct ata_device *dev) { … }