1 #include <linux/libata.h> 2 #include <linux/cdrom.h> 3 #include <linux/pm_runtime.h> 4 #include <linux/module.h> 5 #include <linux/pm_qos.h> 6 #include <scsi/scsi_device.h> 7 8 #include "libata.h" 9 10 static int zpodd_poweroff_delay = 30; /* 30 seconds for power off delay */ 11 module_param(zpodd_poweroff_delay, int, 0644); 12 MODULE_PARM_DESC(zpodd_poweroff_delay, "Poweroff delay for ZPODD in seconds"); 13 14 enum odd_mech_type { 15 ODD_MECH_TYPE_SLOT, 16 ODD_MECH_TYPE_DRAWER, 17 ODD_MECH_TYPE_UNSUPPORTED, 18 }; 19 20 struct zpodd { 21 enum odd_mech_type mech_type; /* init during probe, RO afterwards */ 22 struct ata_device *dev; 23 24 /* The following fields are synchronized by PM core. */ 25 bool from_notify; /* resumed as a result of 26 * acpi wake notification */ 27 bool zp_ready; /* ZP ready state */ 28 unsigned long last_ready; /* last ZP ready timestamp */ 29 bool zp_sampled; /* ZP ready state sampled */ 30 bool powered_off; /* ODD is powered off 31 * during suspend */ 32 }; 33 34 static int eject_tray(struct ata_device *dev) 35 { 36 struct ata_taskfile tf; 37 const char cdb[] = { GPCMD_START_STOP_UNIT, 38 0, 0, 0, 39 0x02, /* LoEj */ 40 0, 0, 0, 0, 0, 0, 0, 41 }; 42 43 ata_tf_init(dev, &tf); 44 tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 45 tf.command = ATA_CMD_PACKET; 46 tf.protocol = ATAPI_PROT_NODATA; 47 48 return ata_exec_internal(dev, &tf, cdb, DMA_NONE, NULL, 0, 0); 49 } 50 51 /* Per the spec, only slot type and drawer type ODD can be supported */ 52 static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev) 53 { 54 char buf[16]; 55 unsigned int ret; 56 struct rm_feature_desc *desc = (void *)(buf + 8); 57 struct ata_taskfile tf; 58 char cdb[] = { GPCMD_GET_CONFIGURATION, 59 2, /* only 1 feature descriptor requested */ 60 0, 3, /* 3, removable medium feature */ 61 0, 0, 0,/* reserved */ 62 0, sizeof(buf), 63 0, 0, 0, 64 }; 65 66 ata_tf_init(dev, &tf); 67 tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 68 tf.command = ATA_CMD_PACKET; 69 tf.protocol = ATAPI_PROT_PIO; 70 tf.lbam = sizeof(buf); 71 72 ret = ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE, 73 buf, sizeof(buf), 0); 74 if (ret) 75 return ODD_MECH_TYPE_UNSUPPORTED; 76 77 if (be16_to_cpu(desc->feature_code) != 3) 78 return ODD_MECH_TYPE_UNSUPPORTED; 79 80 if (desc->mech_type == 0 && desc->load == 0 && desc->eject == 1) 81 return ODD_MECH_TYPE_SLOT; 82 else if (desc->mech_type == 1 && desc->load == 0 && desc->eject == 1) 83 return ODD_MECH_TYPE_DRAWER; 84 else 85 return ODD_MECH_TYPE_UNSUPPORTED; 86 } 87 88 static bool odd_can_poweroff(struct ata_device *ata_dev) 89 { 90 acpi_handle handle; 91 acpi_status status; 92 struct acpi_device *acpi_dev; 93 94 handle = ata_dev_acpi_handle(ata_dev); 95 if (!handle) 96 return false; 97 98 status = acpi_bus_get_device(handle, &acpi_dev); 99 if (ACPI_FAILURE(status)) 100 return false; 101 102 return acpi_device_can_poweroff(acpi_dev); 103 } 104 105 /* Test if ODD is zero power ready by sense code */ 106 static bool zpready(struct ata_device *dev) 107 { 108 u8 sense_key, *sense_buf; 109 unsigned int ret, asc, ascq, add_len; 110 struct zpodd *zpodd = dev->zpodd; 111 112 ret = atapi_eh_tur(dev, &sense_key); 113 114 if (!ret || sense_key != NOT_READY) 115 return false; 116 117 sense_buf = dev->link->ap->sector_buf; 118 ret = atapi_eh_request_sense(dev, sense_buf, sense_key); 119 if (ret) 120 return false; 121 122 /* sense valid */ 123 if ((sense_buf[0] & 0x7f) != 0x70) 124 return false; 125 126 add_len = sense_buf[7]; 127 /* has asc and ascq */ 128 if (add_len < 6) 129 return false; 130 131 asc = sense_buf[12]; 132 ascq = sense_buf[13]; 133 134 if (zpodd->mech_type == ODD_MECH_TYPE_SLOT) 135 /* no media inside */ 136 return asc == 0x3a; 137 else 138 /* no media inside and door closed */ 139 return asc == 0x3a && ascq == 0x01; 140 } 141 142 /* 143 * Update the zpodd->zp_ready field. This field will only be set 144 * if the ODD has stayed in ZP ready state for zpodd_poweroff_delay 145 * time, and will be used to decide if power off is allowed. If it 146 * is set, it will be cleared during resume from powered off state. 147 */ 148 void zpodd_on_suspend(struct ata_device *dev) 149 { 150 struct zpodd *zpodd = dev->zpodd; 151 unsigned long expires; 152 153 if (!zpready(dev)) { 154 zpodd->zp_sampled = false; 155 zpodd->zp_ready = false; 156 return; 157 } 158 159 if (!zpodd->zp_sampled) { 160 zpodd->zp_sampled = true; 161 zpodd->last_ready = jiffies; 162 return; 163 } 164 165 expires = zpodd->last_ready + 166 msecs_to_jiffies(zpodd_poweroff_delay * 1000); 167 if (time_before(jiffies, expires)) 168 return; 169 170 zpodd->zp_ready = true; 171 } 172 173 bool zpodd_zpready(struct ata_device *dev) 174 { 175 struct zpodd *zpodd = dev->zpodd; 176 return zpodd->zp_ready; 177 } 178 179 /* 180 * Enable runtime wake capability through ACPI and set the powered_off flag, 181 * this flag will be used during resume to decide what operations are needed 182 * to take. 183 * 184 * Also, media poll needs to be silenced, so that it doesn't bring the ODD 185 * back to full power state every few seconds. 186 */ 187 void zpodd_enable_run_wake(struct ata_device *dev) 188 { 189 struct zpodd *zpodd = dev->zpodd; 190 191 sdev_disable_disk_events(dev->sdev); 192 193 zpodd->powered_off = true; 194 device_set_run_wake(&dev->tdev, true); 195 acpi_pm_device_run_wake(&dev->tdev, true); 196 } 197 198 /* Disable runtime wake capability if it is enabled */ 199 void zpodd_disable_run_wake(struct ata_device *dev) 200 { 201 struct zpodd *zpodd = dev->zpodd; 202 203 if (zpodd->powered_off) { 204 acpi_pm_device_run_wake(&dev->tdev, false); 205 device_set_run_wake(&dev->tdev, false); 206 } 207 } 208 209 /* 210 * Post power on processing after the ODD has been recovered. If the 211 * ODD wasn't powered off during suspend, it doesn't do anything. 212 * 213 * For drawer type ODD, if it is powered on due to user pressed the 214 * eject button, the tray needs to be ejected. This can only be done 215 * after the ODD has been recovered, i.e. link is initialized and 216 * device is able to process NON_DATA PIO command, as eject needs to 217 * send command for the ODD to process. 218 * 219 * The from_notify flag set in wake notification handler function 220 * zpodd_wake_dev represents if power on is due to user's action. 221 * 222 * For both types of ODD, several fields need to be reset. 223 */ 224 void zpodd_post_poweron(struct ata_device *dev) 225 { 226 struct zpodd *zpodd = dev->zpodd; 227 228 if (!zpodd->powered_off) 229 return; 230 231 zpodd->powered_off = false; 232 233 if (zpodd->from_notify) { 234 zpodd->from_notify = false; 235 if (zpodd->mech_type == ODD_MECH_TYPE_DRAWER) 236 eject_tray(dev); 237 } 238 239 zpodd->zp_sampled = false; 240 zpodd->zp_ready = false; 241 242 sdev_enable_disk_events(dev->sdev); 243 } 244 245 static void zpodd_wake_dev(acpi_handle handle, u32 event, void *context) 246 { 247 struct ata_device *ata_dev = context; 248 struct zpodd *zpodd = ata_dev->zpodd; 249 struct device *dev = &ata_dev->sdev->sdev_gendev; 250 251 if (event == ACPI_NOTIFY_DEVICE_WAKE && pm_runtime_suspended(dev)) { 252 zpodd->from_notify = true; 253 pm_runtime_resume(dev); 254 } 255 } 256 257 static void ata_acpi_add_pm_notifier(struct ata_device *dev) 258 { 259 acpi_handle handle = ata_dev_acpi_handle(dev); 260 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 261 zpodd_wake_dev, dev); 262 } 263 264 static void ata_acpi_remove_pm_notifier(struct ata_device *dev) 265 { 266 acpi_handle handle = ata_dev_acpi_handle(dev); 267 acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, zpodd_wake_dev); 268 } 269 270 void zpodd_init(struct ata_device *dev) 271 { 272 enum odd_mech_type mech_type; 273 struct zpodd *zpodd; 274 275 if (dev->zpodd) 276 return; 277 278 if (!odd_can_poweroff(dev)) 279 return; 280 281 mech_type = zpodd_get_mech_type(dev); 282 if (mech_type == ODD_MECH_TYPE_UNSUPPORTED) 283 return; 284 285 zpodd = kzalloc(sizeof(struct zpodd), GFP_KERNEL); 286 if (!zpodd) 287 return; 288 289 zpodd->mech_type = mech_type; 290 291 ata_acpi_add_pm_notifier(dev); 292 zpodd->dev = dev; 293 dev->zpodd = zpodd; 294 dev_pm_qos_expose_flags(&dev->tdev, 0); 295 } 296 297 void zpodd_exit(struct ata_device *dev) 298 { 299 ata_acpi_remove_pm_notifier(dev); 300 kfree(dev->zpodd); 301 dev->zpodd = NULL; 302 } 303