int generic_ide_suspend(struct device *dev, pm_message_t mesg) { ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; ide_task_t args; int ret; /* call ACPI _GTM only once */ if ((drive->dn & 1) == 0 || pair == NULL) ide_acpi_get_timing(hwif); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_SUSPEND; rq->special = &args; rq->data = &rqpm; rqpm.pm_step = IDE_PM_START_SUSPEND; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; rqpm.pm_state = mesg.event; ret = blk_execute_rq(drive->queue, NULL, rq, 0); blk_put_request(rq); /* call ACPI _PS3 only after both devices are suspended */ if (ret == 0 && ((drive->dn & 1) || pair == NULL)) ide_acpi_set_state(hwif, 0); return ret; }
static int generic_ide_suspend(struct device *dev, pm_message_t mesg) { 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; /* Call ACPI _GTM only once */ if (!(drive->dn % 2)) ide_acpi_get_timing(hwif); memset(&rq, 0, sizeof(rq)); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); rq.cmd_type = REQ_TYPE_PM_SUSPEND; rq.special = &args; rq.data = &rqpm; rqpm.pm_step = ide_pm_state_start_suspend; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; rqpm.pm_state = mesg.event; return ide_do_drive_cmd(drive, &rq, ide_wait); }
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_suspend(struct device *dev, pm_message_t mesg) { ide_drive_t *drive = to_ide_device(dev); ide_drive_t *pair = ide_get_pair_dev(drive); ide_hwif_t *hwif = drive->hwif; struct request *rq; struct ide_pm_state rqpm; int ret; if (ide_port_acpi(hwif)) { /* call ACPI _GTM only once */ if ((drive->dn & 1) == 0 || pair == NULL) ide_acpi_get_timing(hwif); } memset(&rqpm, 0, sizeof(rqpm)); rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, __GFP_RECLAIM); ide_req(rq)->type = ATA_PRIV_PM_SUSPEND; rq->special = &rqpm; rqpm.pm_step = IDE_PM_START_SUSPEND; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; rqpm.pm_state = mesg.event; blk_execute_rq(drive->queue, NULL, rq, 0); ret = scsi_req(rq)->result ? -EIO : 0; blk_put_request(rq); if (ret == 0 && ide_port_acpi(hwif)) { /* call ACPI _PS3 only after both devices are suspended */ if ((drive->dn & 1) || pair == NULL) ide_acpi_set_state(hwif, 0); } return ret; }