static int generic_ide_resume(struct device *dev) { ide_drive_t *drive = dev->driver_data; ide_hwif_t *hwif = HWIF(drive); struct request rq; struct request_pm_state rqpm; ide_task_t args; int err; /* Call ACPI _STM only once */ if (!(drive->dn % 2)) ide_acpi_push_timing(hwif); ide_acpi_exec_tfs(drive); memset(&rq, 0, sizeof(rq)); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); rq.cmd_type = REQ_TYPE_PM_RESUME; rq.special = &args; rq.data = &rqpm; rqpm.pm_step = ide_pm_state_start_resume; rqpm.pm_state = PM_EVENT_ON; err = ide_do_drive_cmd(drive, &rq, ide_head_wait); if (err == 0 && dev->driver) { ide_driver_t *drv = to_ide_driver(dev->driver); if (drv->resume) drv->resume(drive); } return err; }
void ide_acpi_port_init_devices(ide_hwif_t *hwif) { ide_drive_t *drive; int i, err; if (hwif->acpidata == NULL) return; /* * The ACPI spec mandates that we send information * for both drives, regardless whether they are connected * or not. */ hwif->drives[0].acpidata = &hwif->acpidata->master; hwif->drives[1].acpidata = &hwif->acpidata->slave; /* * Send IDENTIFY for each drive */ for (i = 0; i < MAX_DRIVES; i++) { drive = &hwif->drives[i]; if (!drive->present) continue; err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff); if (err) DEBPRINT("identify device %s failed (%d)\n", drive->name, err); } if (ide_noacpionboot) { DEBPRINT("ACPI methods disabled on boot\n"); return; } /* ACPI _PS0 before _STM */ ide_acpi_set_state(hwif, 1); /* * ACPI requires us to call _STM on startup */ ide_acpi_get_timing(hwif); ide_acpi_push_timing(hwif); for (i = 0; i < MAX_DRIVES; i++) { drive = &hwif->drives[i]; if (drive->present) /* Execute ACPI startup code */ ide_acpi_exec_tfs(drive); } }
int generic_ide_resume(struct device *dev) { ide_drive_t *drive = dev_get_drvdata(dev); ide_drive_t *pair = ide_get_pair_dev(drive); ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; int err; if (ide_port_acpi(hwif)) { /* call ACPI _PS0 / _STM only once */ if ((drive->dn & 1) == 0 || pair == NULL) { ide_acpi_set_state(hwif, 1); ide_acpi_push_timing(hwif); } ide_acpi_exec_tfs(drive); } memset(&rqpm, 0, sizeof(rqpm)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_RESUME; rq->cmd_flags |= REQ_PREEMPT; rq->special = &rqpm; rqpm.pm_step = IDE_PM_START_RESUME; rqpm.pm_state = PM_EVENT_ON; err = blk_execute_rq(drive->queue, NULL, rq, 1); blk_put_request(rq); if (err == 0 && dev->driver) { struct ide_driver *drv = to_ide_driver(dev->driver); if (drv->resume) drv->resume(drive); } return err; }