Blame view

drivers/ata/libata-acpi.c 26.2 KB
457c89965   Thomas Gleixner   treewide: Add SPD...
1
  // SPDX-License-Identifier: GPL-2.0-only
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
2
3
4
5
6
7
8
  /*
   * libata-acpi.c
   * Provides ACPI support for PATA/SATA.
   *
   * Copyright (C) 2006 Intel Corp.
   * Copyright (C) 2006 Randy Dunlap
   */
3264a8d8f   Tejun Heo   libata-acpi: impl...
9
  #include <linux/module.h>
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
10
11
12
13
14
15
16
17
  #include <linux/ata.h>
  #include <linux/delay.h>
  #include <linux/device.h>
  #include <linux/errno.h>
  #include <linux/kernel.h>
  #include <linux/acpi.h>
  #include <linux/libata.h>
  #include <linux/pci.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
18
  #include <linux/slab.h>
3bd46600a   Lin Ming   libata-acpi: add ...
19
  #include <linux/pm_runtime.h>
237d8440c   Matthew Garrett   libata: Integrate...
20
  #include <scsi/scsi_device.h>
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
21
  #include "libata.h"
110f66d25   Tejun Heo   libata: make gtf_...
22
  unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT;
3264a8d8f   Tejun Heo   libata-acpi: impl...
23
  module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644);
fa5b561c4   Tejun Heo   libata: implement...
24
  MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM, 0x8=FPDMA non-zero offset, 0x10=FPDMA DMA Setup FIS auto-activate)");
3264a8d8f   Tejun Heo   libata-acpi: impl...
25

11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
26
  #define NO_PORT_MULT		0xffff
2dcb407e6   Jeff Garzik   [libata] checkpat...
27
  #define SATA_ADR(root, pmp)	(((root) << 16) | (pmp))
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
28
29
  
  #define REGS_PER_GTF		7
4700c4bc9   Tejun Heo   libata-acpi: clea...
30
31
32
  struct ata_acpi_gtf {
  	u8	tf[REGS_PER_GTF];	/* regs. 0x1f1 - 0x1f7 */
  } __packed;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
33

398e07826   Tejun Heo   libata-acpi: impl...
34
35
36
37
38
  static void ata_acpi_clear_gtf(struct ata_device *dev)
  {
  	kfree(dev->gtf_cache);
  	dev->gtf_cache = NULL;
  }
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
39
40
41
42
43
44
45
46
47
  struct ata_acpi_hotplug_context {
  	struct acpi_hotplug_context hp;
  	union {
  		struct ata_port *ap;
  		struct ata_device *dev;
  	} data;
  };
  
  #define ata_hotplug_data(context) (container_of((context), struct ata_acpi_hotplug_context, hp)->data)
30dcf76ac   Matthew Garrett   libata: migrate A...
48
  /**
30dcf76ac   Matthew Garrett   libata: migrate A...
49
   * ata_dev_acpi_handle - provide the acpi_handle for an ata_device
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
50
   * @dev: the acpi_handle returned will correspond to this device
30dcf76ac   Matthew Garrett   libata: migrate A...
51
52
53
   *
   * Returns the acpi_handle for the ACPI namespace object corresponding to
   * the ata_device passed into the function, or NULL if no such object exists
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
54
   * or ACPI is disabled for this device due to consecutive errors.
30dcf76ac   Matthew Garrett   libata: migrate A...
55
56
   */
  acpi_handle ata_dev_acpi_handle(struct ata_device *dev)
6b66d9589   Matthew Garrett   libata: bind the ...
57
  {
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
58
59
  	return dev->flags & ATA_DFLAG_ACPI_DISABLED ?
  			NULL : ACPI_HANDLE(&dev->tdev);
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
60
  }
664d080c4   Holger Macht   [libata] ACPI: Pr...
61
62
63
64
65
66
67
68
  /* @ap and @dev are the same as ata_acpi_handle_hotplug() */
  static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
  {
  	if (dev)
  		dev->flags |= ATA_DFLAG_DETACH;
  	else {
  		struct ata_link *tlink;
  		struct ata_device *tdev;
1eca4365b   Tejun Heo   libata: beef up i...
69
70
  		ata_for_each_link(tlink, ap, EDGE)
  			ata_for_each_dev(tdev, tlink, ALL)
664d080c4   Holger Macht   [libata] ACPI: Pr...
71
72
73
74
75
76
77
78
79
80
81
  				tdev->flags |= ATA_DFLAG_DETACH;
  	}
  
  	ata_port_schedule_eh(ap);
  }
  
  /**
   * ata_acpi_handle_hotplug - ACPI event handler backend
   * @ap: ATA port ACPI event occurred
   * @dev: ATA device ACPI event occurred (can be NULL)
   * @event: ACPI event which occurred
664d080c4   Holger Macht   [libata] ACPI: Pr...
82
83
84
85
86
87
88
89
90
91
92
93
94
   *
   * All ACPI bay / device realted events end up in this function.  If
   * the event is port-wide @dev is NULL.  If the event is specific to a
   * device, @dev points to it.
   *
   * Hotplug (as opposed to unplug) notification is always handled as
   * port-wide while unplug only kills the target device on device-wide
   * event.
   *
   * LOCKING:
   * ACPI notify handler context.  May sleep.
   */
  static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
f730ae183   Shaohua Li   libata: remove fu...
95
  				    u32 event)
237d8440c   Matthew Garrett   libata: Integrate...
96
  {
664d080c4   Holger Macht   [libata] ACPI: Pr...
97
  	struct ata_eh_info *ehi = &ap->link.eh_info;
233f11204   Tejun Heo   libata-acpi: impr...
98
99
  	int wait = 0;
  	unsigned long flags;
3c1e38963   Zhang Rui   libata-acpi: don'...
100

664d080c4   Holger Macht   [libata] ACPI: Pr...
101
  	spin_lock_irqsave(ap->lock, flags);
f730ae183   Shaohua Li   libata: remove fu...
102
103
104
105
106
  	/*
  	 * When dock driver calls into the routine, it will always use
  	 * ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and
  	 * ACPI_NOTIFY_EJECT_REQUEST for remove
  	 */
233f11204   Tejun Heo   libata-acpi: impr...
107
108
109
110
  	switch (event) {
  	case ACPI_NOTIFY_BUS_CHECK:
  	case ACPI_NOTIFY_DEVICE_CHECK:
  		ata_ehi_push_desc(ehi, "ACPI event");
664d080c4   Holger Macht   [libata] ACPI: Pr...
111

f730ae183   Shaohua Li   libata: remove fu...
112
113
  		ata_ehi_hotplugged(ehi);
  		ata_port_freeze(ap);
664d080c4   Holger Macht   [libata] ACPI: Pr...
114
115
116
  		break;
  	case ACPI_NOTIFY_EJECT_REQUEST:
  		ata_ehi_push_desc(ehi, "ACPI event");
664d080c4   Holger Macht   [libata] ACPI: Pr...
117
118
119
  		ata_acpi_detach_device(ap, dev);
  		wait = 1;
  		break;
237d8440c   Matthew Garrett   libata: Integrate...
120
  	}
ae6c23c4e   Matthew Garrett   Fixups to ATA ACP...
121
  	spin_unlock_irqrestore(ap->lock, flags);
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
122
  	if (wait)
ae6c23c4e   Matthew Garrett   Fixups to ATA ACP...
123
  		ata_port_wait_eh(ap);
664d080c4   Holger Macht   [libata] ACPI: Pr...
124
  }
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
125
  static int ata_acpi_dev_notify_dock(struct acpi_device *adev, u32 event)
664d080c4   Holger Macht   [libata] ACPI: Pr...
126
  {
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
127
  	struct ata_device *dev = ata_hotplug_data(adev->hp).dev;
f730ae183   Shaohua Li   libata: remove fu...
128
  	ata_acpi_handle_hotplug(dev->link->ap, dev, event);
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
129
  	return 0;
664d080c4   Holger Macht   [libata] ACPI: Pr...
130
  }
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
131
  static int ata_acpi_ap_notify_dock(struct acpi_device *adev, u32 event)
664d080c4   Holger Macht   [libata] ACPI: Pr...
132
  {
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
133
134
  	ata_acpi_handle_hotplug(ata_hotplug_data(adev->hp).ap, NULL, event);
  	return 0;
237d8440c   Matthew Garrett   libata: Integrate...
135
  }
1253f7aab   Shaohua Li   dock: introduce ....
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
  	u32 event)
  {
  	struct kobject *kobj = NULL;
  	char event_string[20];
  	char *envp[] = { event_string, NULL };
  
  	if (dev) {
  		if (dev->sdev)
  			kobj = &dev->sdev->sdev_gendev.kobj;
  	} else
  		kobj = &ap->dev->kobj;
  
  	if (kobj) {
  		snprintf(event_string, 20, "BAY_EVENT=%d", event);
  		kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
  	}
  }
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
154
  static void ata_acpi_ap_uevent(struct acpi_device *adev, u32 event)
1253f7aab   Shaohua Li   dock: introduce ....
155
  {
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
156
  	ata_acpi_uevent(ata_hotplug_data(adev->hp).ap, NULL, event);
1253f7aab   Shaohua Li   dock: introduce ....
157
  }
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
158
  static void ata_acpi_dev_uevent(struct acpi_device *adev, u32 event)
1253f7aab   Shaohua Li   dock: introduce ....
159
  {
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
160
  	struct ata_device *dev = ata_hotplug_data(adev->hp).dev;
1253f7aab   Shaohua Li   dock: introduce ....
161
162
  	ata_acpi_uevent(dev->link->ap, dev, event);
  }
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
163
164
  /* bind acpi handle to pata port */
  void ata_acpi_bind_port(struct ata_port *ap)
44521527b   Aaron Lu   libata-acpi: add ...
165
  {
9c5ad36d9   Rafael J. Wysocki   ACPI / bind: Rede...
166
  	struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev);
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
167
168
  	struct acpi_device *adev;
  	struct ata_acpi_hotplug_context *context;
44521527b   Aaron Lu   libata-acpi: add ...
169

9c5ad36d9   Rafael J. Wysocki   ACPI / bind: Rede...
170
  	if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_companion)
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
171
  		return;
44521527b   Aaron Lu   libata-acpi: add ...
172

9c5ad36d9   Rafael J. Wysocki   ACPI / bind: Rede...
173
  	acpi_preset_companion(&ap->tdev, host_companion, ap->port_no);
44521527b   Aaron Lu   libata-acpi: add ...
174

f1bc1e4c4   Aaron Lu   ata: acpi: rework...
175
176
  	if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
  		ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
44521527b   Aaron Lu   libata-acpi: add ...
177

5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
178
179
180
181
182
183
184
185
186
187
188
  	adev = ACPI_COMPANION(&ap->tdev);
  	if (!adev || adev->hp)
  		return;
  
  	context = kzalloc(sizeof(*context), GFP_KERNEL);
  	if (!context)
  		return;
  
  	context->data.ap = ap;
  	acpi_initialize_hp_context(adev, &context->hp, ata_acpi_ap_notify_dock,
  				   ata_acpi_ap_uevent);
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
189
  }
44521527b   Aaron Lu   libata-acpi: add ...
190

f1bc1e4c4   Aaron Lu   ata: acpi: rework...
191
192
193
  void ata_acpi_bind_dev(struct ata_device *dev)
  {
  	struct ata_port *ap = dev->link->ap;
9c5ad36d9   Rafael J. Wysocki   ACPI / bind: Rede...
194
195
  	struct acpi_device *port_companion = ACPI_COMPANION(&ap->tdev);
  	struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev);
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
196
197
  	struct acpi_device *parent, *adev;
  	struct ata_acpi_hotplug_context *context;
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
198
199
200
  	u64 adr;
  
  	/*
9c5ad36d9   Rafael J. Wysocki   ACPI / bind: Rede...
201
202
  	 * For both sata/pata devices, host companion device is required.
  	 * For pata device, port companion device is also required.
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
203
  	 */
9c5ad36d9   Rafael J. Wysocki   ACPI / bind: Rede...
204
205
  	if (libata_noacpi || !host_companion ||
  			(!(ap->flags & ATA_FLAG_ACPI_SATA) && !port_companion))
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
206
207
208
209
210
211
212
  		return;
  
  	if (ap->flags & ATA_FLAG_ACPI_SATA) {
  		if (!sata_pmp_attached(ap))
  			adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
  		else
  			adr = SATA_ADR(ap->port_no, dev->link->pmp);
9c5ad36d9   Rafael J. Wysocki   ACPI / bind: Rede...
213
  		parent = host_companion;
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
214
215
  	} else {
  		adr = dev->devno;
9c5ad36d9   Rafael J. Wysocki   ACPI / bind: Rede...
216
  		parent = port_companion;
44521527b   Aaron Lu   libata-acpi: add ...
217
  	}
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
218

9c5ad36d9   Rafael J. Wysocki   ACPI / bind: Rede...
219
  	acpi_preset_companion(&dev->tdev, parent, adr);
5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
220
221
222
223
224
225
226
  	adev = ACPI_COMPANION(&dev->tdev);
  	if (!adev || adev->hp)
  		return;
  
  	context = kzalloc(sizeof(*context), GFP_KERNEL);
  	if (!context)
  		return;
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
227

5d5132059   Rafael J. Wysocki   ACPI / ATA: Add h...
228
229
230
  	context->data.dev = dev;
  	acpi_initialize_hp_context(adev, &context->hp, ata_acpi_dev_notify_dock,
  				   ata_acpi_dev_uevent);
44521527b   Aaron Lu   libata-acpi: add ...
231
  }
fafbae87d   Tejun Heo   libata-acpi: impl...
232
  /**
562f0c2d7   Tejun Heo   libata-acpi: add ...
233
234
235
236
237
238
239
240
241
242
243
   * ata_acpi_dissociate - dissociate ATA host from ACPI objects
   * @host: target ATA host
   *
   * This function is called during driver detach after the whole host
   * is shut down.
   *
   * LOCKING:
   * EH context.
   */
  void ata_acpi_dissociate(struct ata_host *host)
  {
c05e6ff03   Tejun Heo   libata-acpi: impl...
244
245
246
247
248
249
250
251
  	int i;
  
  	/* Restore initial _GTM values so that driver which attaches
  	 * afterward can use them too.
  	 */
  	for (i = 0; i < host->n_ports; i++) {
  		struct ata_port *ap = host->ports[i];
  		const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
252
  		if (ACPI_HANDLE(&ap->tdev) && gtm)
c05e6ff03   Tejun Heo   libata-acpi: impl...
253
254
  			ata_acpi_stm(ap, gtm);
  	}
562f0c2d7   Tejun Heo   libata-acpi: add ...
255
  }
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  /**
   * ata_acpi_gtm - execute _GTM
   * @ap: target ATA port
   * @gtm: out parameter for _GTM result
   *
   * Evaluate _GTM and store the result in @gtm.
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
   * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
   */
  int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
64578a3de   Tejun Heo   libata-acpi: impl...
270
271
272
273
274
  {
  	struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
  	union acpi_object *out_obj;
  	acpi_status status;
  	int rc = 0;
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
275
276
277
278
  	acpi_handle handle = ACPI_HANDLE(&ap->tdev);
  
  	if (!handle)
  		return -EINVAL;
64578a3de   Tejun Heo   libata-acpi: impl...
279

d66af4df0   Aaron Lu   [libata] acpi: ma...
280
  	status = acpi_evaluate_object(handle, "_GTM", NULL, &output);
64578a3de   Tejun Heo   libata-acpi: impl...
281
282
283
284
285
286
287
  
  	rc = -ENOENT;
  	if (status == AE_NOT_FOUND)
  		goto out_free;
  
  	rc = -EINVAL;
  	if (ACPI_FAILURE(status)) {
a9a79dfec   Joe Perches   ata: Convert ata_...
288
289
290
  		ata_port_err(ap, "ACPI get timing mode failed (AE 0x%x)
  ",
  			     status);
64578a3de   Tejun Heo   libata-acpi: impl...
291
292
293
294
295
  		goto out_free;
  	}
  
  	out_obj = output.pointer;
  	if (out_obj->type != ACPI_TYPE_BUFFER) {
a9a79dfec   Joe Perches   ata: Convert ata_...
296
297
298
  		ata_port_warn(ap, "_GTM returned unexpected object type 0x%x
  ",
  			      out_obj->type);
64578a3de   Tejun Heo   libata-acpi: impl...
299
300
301
302
303
  
  		goto out_free;
  	}
  
  	if (out_obj->buffer.length != sizeof(struct ata_acpi_gtm)) {
a9a79dfec   Joe Perches   ata: Convert ata_...
304
305
306
  		ata_port_err(ap, "_GTM returned invalid length %d
  ",
  			     out_obj->buffer.length);
64578a3de   Tejun Heo   libata-acpi: impl...
307
308
309
310
311
312
313
314
315
  		goto out_free;
  	}
  
  	memcpy(gtm, out_obj->buffer.pointer, sizeof(struct ata_acpi_gtm));
  	rc = 0;
   out_free:
  	kfree(output.pointer);
  	return rc;
  }
badff03df   Alan Cox   libata-core: Expo...
316
  EXPORT_SYMBOL_GPL(ata_acpi_gtm);
64578a3de   Tejun Heo   libata-acpi: impl...
317
318
319
320
321
322
323
324
325
326
327
328
329
  /**
   * ata_acpi_stm - execute _STM
   * @ap: target ATA port
   * @stm: timing parameter to _STM
   *
   * Evaluate _STM with timing parameter @stm.
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
   * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure.
   */
0d02f0b22   Tejun Heo   libata-acpi: adju...
330
  int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm)
64578a3de   Tejun Heo   libata-acpi: impl...
331
332
  {
  	acpi_status status;
0d02f0b22   Tejun Heo   libata-acpi: adju...
333
  	struct ata_acpi_gtm		stm_buf = *stm;
64578a3de   Tejun Heo   libata-acpi: impl...
334
335
336
337
338
  	struct acpi_object_list         input;
  	union acpi_object               in_params[3];
  
  	in_params[0].type = ACPI_TYPE_BUFFER;
  	in_params[0].buffer.length = sizeof(struct ata_acpi_gtm);
0d02f0b22   Tejun Heo   libata-acpi: adju...
339
  	in_params[0].buffer.pointer = (u8 *)&stm_buf;
64578a3de   Tejun Heo   libata-acpi: impl...
340
341
342
  	/* Buffers for id may need byteswapping ? */
  	in_params[1].type = ACPI_TYPE_BUFFER;
  	in_params[1].buffer.length = 512;
9af5c9c97   Tejun Heo   libata-link: intr...
343
  	in_params[1].buffer.pointer = (u8 *)ap->link.device[0].id;
64578a3de   Tejun Heo   libata-acpi: impl...
344
345
  	in_params[2].type = ACPI_TYPE_BUFFER;
  	in_params[2].buffer.length = 512;
9af5c9c97   Tejun Heo   libata-link: intr...
346
  	in_params[2].buffer.pointer = (u8 *)ap->link.device[1].id;
64578a3de   Tejun Heo   libata-acpi: impl...
347
348
349
  
  	input.count = 3;
  	input.pointer = in_params;
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
350
351
  	status = acpi_evaluate_object(ACPI_HANDLE(&ap->tdev), "_STM",
  				      &input, NULL);
64578a3de   Tejun Heo   libata-acpi: impl...
352
353
354
355
  
  	if (status == AE_NOT_FOUND)
  		return -ENOENT;
  	if (ACPI_FAILURE(status)) {
a9a79dfec   Joe Perches   ata: Convert ata_...
356
357
358
  		ata_port_err(ap, "ACPI set timing mode failed (status=0x%x)
  ",
  			     status);
64578a3de   Tejun Heo   libata-acpi: impl...
359
360
361
362
  		return -EINVAL;
  	}
  	return 0;
  }
badff03df   Alan Cox   libata-core: Expo...
363
  EXPORT_SYMBOL_GPL(ata_acpi_stm);
64578a3de   Tejun Heo   libata-acpi: impl...
364
  /**
4700c4bc9   Tejun Heo   libata-acpi: clea...
365
   * ata_dev_get_GTF - get the drive bootup default taskfile settings
3a32a8e96   Tejun Heo   libata-acpi: clea...
366
   * @dev: target ATA device
4700c4bc9   Tejun Heo   libata-acpi: clea...
367
   * @gtf: output parameter for buffer containing _GTF taskfile arrays
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
368
369
370
371
372
373
374
375
376
   *
   * This applies to both PATA and SATA drives.
   *
   * The _GTF method has no input parameters.
   * It returns a variable number of register set values (registers
   * hex 1F1..1F7, taskfiles).
   * The <variable number> is not known in advance, so have ACPI-CA
   * allocate the buffer as needed and return it, then free it later.
   *
4700c4bc9   Tejun Heo   libata-acpi: clea...
377
378
379
380
   * LOCKING:
   * EH context.
   *
   * RETURNS:
66fa7f215   Tejun Heo   libata-acpi: impr...
381
382
   * Number of taskfiles on success, 0 if _GTF doesn't exist.  -EINVAL
   * if _GTF is invalid.
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
383
   */
398e07826   Tejun Heo   libata-acpi: impl...
384
  static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
385
  {
9af5c9c97   Tejun Heo   libata-link: intr...
386
  	struct ata_port *ap = dev->link->ap;
3a32a8e96   Tejun Heo   libata-acpi: clea...
387
  	acpi_status status;
3a32a8e96   Tejun Heo   libata-acpi: clea...
388
389
  	struct acpi_buffer output;
  	union acpi_object *out_obj;
4700c4bc9   Tejun Heo   libata-acpi: clea...
390
  	int rc = 0;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
391

398e07826   Tejun Heo   libata-acpi: impl...
392
393
394
395
396
  	/* if _GTF is cached, use the cached value */
  	if (dev->gtf_cache) {
  		out_obj = dev->gtf_cache;
  		goto done;
  	}
4700c4bc9   Tejun Heo   libata-acpi: clea...
397
398
399
  	/* set up output buffer */
  	output.length = ACPI_ALLOCATE_BUFFER;
  	output.pointer = NULL;	/* ACPI-CA sets this; save/free it later */
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
400

11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
401
  	if (ata_msg_probe(ap))
a9a79dfec   Joe Perches   ata: Convert ata_...
402
403
404
  		ata_dev_dbg(dev, "%s: ENTER: port#: %d
  ",
  			    __func__, ap->port_no);
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
405

11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
406
  	/* _GTF has no input parameters */
30dcf76ac   Matthew Garrett   libata: migrate A...
407
408
  	status = acpi_evaluate_object(ata_dev_acpi_handle(dev), "_GTF", NULL,
  				      &output);
398e07826   Tejun Heo   libata-acpi: impl...
409
  	out_obj = dev->gtf_cache = output.pointer;
4700c4bc9   Tejun Heo   libata-acpi: clea...
410

11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
411
  	if (ACPI_FAILURE(status)) {
4700c4bc9   Tejun Heo   libata-acpi: clea...
412
  		if (status != AE_NOT_FOUND) {
a9a79dfec   Joe Perches   ata: Convert ata_...
413
414
415
  			ata_dev_warn(dev, "_GTF evaluation failed (AE 0x%x)
  ",
  				     status);
66fa7f215   Tejun Heo   libata-acpi: impr...
416
  			rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
417
418
  		}
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
419
420
421
422
  	}
  
  	if (!output.length || !output.pointer) {
  		if (ata_msg_probe(ap))
a9a79dfec   Joe Perches   ata: Convert ata_...
423
424
425
426
427
  			ata_dev_dbg(dev, "%s: Run _GTF: length or ptr is NULL (0x%llx, 0x%p)
  ",
  				    __func__,
  				    (unsigned long long)output.length,
  				    output.pointer);
66fa7f215   Tejun Heo   libata-acpi: impr...
428
  		rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
429
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
430
  	}
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
431
  	if (out_obj->type != ACPI_TYPE_BUFFER) {
a9a79dfec   Joe Perches   ata: Convert ata_...
432
433
434
  		ata_dev_warn(dev, "_GTF unexpected object type 0x%x
  ",
  			     out_obj->type);
66fa7f215   Tejun Heo   libata-acpi: impr...
435
  		rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
436
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
437
  	}
4700c4bc9   Tejun Heo   libata-acpi: clea...
438
  	if (out_obj->buffer.length % REGS_PER_GTF) {
a9a79dfec   Joe Perches   ata: Convert ata_...
439
440
441
  		ata_dev_warn(dev, "unexpected _GTF length (%d)
  ",
  			     out_obj->buffer.length);
66fa7f215   Tejun Heo   libata-acpi: impr...
442
  		rc = -EINVAL;
4700c4bc9   Tejun Heo   libata-acpi: clea...
443
  		goto out_free;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
444
  	}
398e07826   Tejun Heo   libata-acpi: impl...
445
   done:
4700c4bc9   Tejun Heo   libata-acpi: clea...
446
  	rc = out_obj->buffer.length / REGS_PER_GTF;
398e07826   Tejun Heo   libata-acpi: impl...
447
448
449
  	if (gtf) {
  		*gtf = (void *)out_obj->buffer.pointer;
  		if (ata_msg_probe(ap))
a9a79dfec   Joe Perches   ata: Convert ata_...
450
451
452
  			ata_dev_dbg(dev, "%s: returning gtf=%p, gtf_count=%d
  ",
  				    __func__, *gtf, rc);
398e07826   Tejun Heo   libata-acpi: impl...
453
  	}
4700c4bc9   Tejun Heo   libata-acpi: clea...
454
455
456
  	return rc;
  
   out_free:
398e07826   Tejun Heo   libata-acpi: impl...
457
  	ata_acpi_clear_gtf(dev);
4700c4bc9   Tejun Heo   libata-acpi: clea...
458
  	return rc;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
459
  }
7c77fa4d5   Tejun Heo   libata: separate ...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
  /**
   * ata_acpi_gtm_xfermode - determine xfermode from GTM parameter
   * @dev: target device
   * @gtm: GTM parameter to use
   *
   * Determine xfermask for @dev from @gtm.
   *
   * LOCKING:
   * None.
   *
   * RETURNS:
   * Determined xfermask.
   */
  unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev,
  				    const struct ata_acpi_gtm *gtm)
  {
a0f79b929   Tejun Heo   libata: implement...
476
477
478
479
  	unsigned long xfer_mask = 0;
  	unsigned int type;
  	int unit;
  	u8 mode;
7c77fa4d5   Tejun Heo   libata: separate ...
480
481
482
483
484
  
  	/* we always use the 0 slot for crap hardware */
  	unit = dev->devno;
  	if (!(gtm->flags & 0x10))
  		unit = 0;
a0f79b929   Tejun Heo   libata: implement...
485
486
487
  	/* PIO */
  	mode = ata_timing_cycle2mode(ATA_SHIFT_PIO, gtm->drive[unit].pio);
  	xfer_mask |= ata_xfer_mode2mask(mode);
7c77fa4d5   Tejun Heo   libata: separate ...
488
489
490
491
492
  
  	/* See if we have MWDMA or UDMA data. We don't bother with
  	 * MWDMA if UDMA is available as this means the BIOS set UDMA
  	 * and our error changedown if it works is UDMA to PIO anyway.
  	 */
a0f79b929   Tejun Heo   libata: implement...
493
494
495
496
497
498
499
  	if (!(gtm->flags & (1 << (2 * unit))))
  		type = ATA_SHIFT_MWDMA;
  	else
  		type = ATA_SHIFT_UDMA;
  
  	mode = ata_timing_cycle2mode(type, gtm->drive[unit].dma);
  	xfer_mask |= ata_xfer_mode2mask(mode);
7c77fa4d5   Tejun Heo   libata: separate ...
500

a0f79b929   Tejun Heo   libata: implement...
501
  	return xfer_mask;
7c77fa4d5   Tejun Heo   libata: separate ...
502
503
  }
  EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask);
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
504
  /**
e1ddb4b6a   Alan Cox   [libata] add ACPI...
505
506
   * ata_acpi_cbl_80wire		-	Check for 80 wire cable
   * @ap: Port to check
021ee9a6d   Tejun Heo   libata: reimpleme...
507
   * @gtm: GTM data to use
e1ddb4b6a   Alan Cox   [libata] add ACPI...
508
   *
021ee9a6d   Tejun Heo   libata: reimpleme...
509
   * Return 1 if the @gtm indicates the BIOS selected an 80wire mode.
e1ddb4b6a   Alan Cox   [libata] add ACPI...
510
   */
021ee9a6d   Tejun Heo   libata: reimpleme...
511
  int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm)
e1ddb4b6a   Alan Cox   [libata] add ACPI...
512
  {
021ee9a6d   Tejun Heo   libata: reimpleme...
513
  	struct ata_device *dev;
1eca4365b   Tejun Heo   libata: beef up i...
514
  	ata_for_each_dev(dev, &ap->link, ENABLED) {
021ee9a6d   Tejun Heo   libata: reimpleme...
515
  		unsigned long xfer_mask, udma_mask;
021ee9a6d   Tejun Heo   libata: reimpleme...
516
517
518
519
520
521
  		xfer_mask = ata_acpi_gtm_xfermask(dev, gtm);
  		ata_unpack_xfermask(xfer_mask, NULL, NULL, &udma_mask);
  
  		if (udma_mask & ~ATA_UDMA_MASK_40C)
  			return 1;
  	}
e1ddb4b6a   Alan Cox   [libata] add ACPI...
522
523
  	return 0;
  }
e1ddb4b6a   Alan Cox   [libata] add ACPI...
524
  EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire);
3264a8d8f   Tejun Heo   libata-acpi: impl...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
  static void ata_acpi_gtf_to_tf(struct ata_device *dev,
  			       const struct ata_acpi_gtf *gtf,
  			       struct ata_taskfile *tf)
  {
  	ata_tf_init(dev, tf);
  
  	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
  	tf->protocol = ATA_PROT_NODATA;
  	tf->feature = gtf->tf[0];	/* 0x1f1 */
  	tf->nsect   = gtf->tf[1];	/* 0x1f2 */
  	tf->lbal    = gtf->tf[2];	/* 0x1f3 */
  	tf->lbam    = gtf->tf[3];	/* 0x1f4 */
  	tf->lbah    = gtf->tf[4];	/* 0x1f5 */
  	tf->device  = gtf->tf[5];	/* 0x1f6 */
  	tf->command = gtf->tf[6];	/* 0x1f7 */
  }
110f66d25   Tejun Heo   libata: make gtf_...
541
542
  static int ata_acpi_filter_tf(struct ata_device *dev,
  			      const struct ata_taskfile *tf,
3264a8d8f   Tejun Heo   libata-acpi: impl...
543
544
  			      const struct ata_taskfile *ptf)
  {
110f66d25   Tejun Heo   libata: make gtf_...
545
  	if (dev->gtf_filter & ATA_ACPI_FILTER_SETXFER) {
3264a8d8f   Tejun Heo   libata-acpi: impl...
546
547
548
549
550
551
552
  		/* libata doesn't use ACPI to configure transfer mode.
  		 * It will only confuse device configuration.  Skip.
  		 */
  		if (tf->command == ATA_CMD_SET_FEATURES &&
  		    tf->feature == SETFEATURES_XFER)
  			return 1;
  	}
110f66d25   Tejun Heo   libata: make gtf_...
553
  	if (dev->gtf_filter & ATA_ACPI_FILTER_LOCK) {
3264a8d8f   Tejun Heo   libata-acpi: impl...
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
  		/* BIOS writers, sorry but we don't wanna lock
  		 * features unless the user explicitly said so.
  		 */
  
  		/* DEVICE CONFIGURATION FREEZE LOCK */
  		if (tf->command == ATA_CMD_CONF_OVERLAY &&
  		    tf->feature == ATA_DCO_FREEZE_LOCK)
  			return 1;
  
  		/* SECURITY FREEZE LOCK */
  		if (tf->command == ATA_CMD_SEC_FREEZE_LOCK)
  			return 1;
  
  		/* SET MAX LOCK and SET MAX FREEZE LOCK */
  		if ((!ptf || ptf->command != ATA_CMD_READ_NATIVE_MAX) &&
  		    tf->command == ATA_CMD_SET_MAX &&
  		    (tf->feature == ATA_SET_MAX_LOCK ||
  		     tf->feature == ATA_SET_MAX_FREEZE_LOCK))
  			return 1;
  	}
fa5b561c4   Tejun Heo   libata: implement...
574
575
  	if (tf->command == ATA_CMD_SET_FEATURES &&
  	    tf->feature == SETFEATURES_SATA_ENABLE) {
b344991ac   Tejun Heo   libata-acpi: filt...
576
  		/* inhibit enabling DIPM */
110f66d25   Tejun Heo   libata: make gtf_...
577
  		if (dev->gtf_filter & ATA_ACPI_FILTER_DIPM &&
b344991ac   Tejun Heo   libata-acpi: filt...
578
579
  		    tf->nsect == SATA_DIPM)
  			return 1;
fa5b561c4   Tejun Heo   libata: implement...
580
581
  
  		/* inhibit FPDMA non-zero offset */
110f66d25   Tejun Heo   libata: make gtf_...
582
  		if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_OFFSET &&
fa5b561c4   Tejun Heo   libata: implement...
583
584
585
586
587
  		    (tf->nsect == SATA_FPDMA_OFFSET ||
  		     tf->nsect == SATA_FPDMA_IN_ORDER))
  			return 1;
  
  		/* inhibit FPDMA auto activation */
110f66d25   Tejun Heo   libata: make gtf_...
588
  		if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_AA &&
fa5b561c4   Tejun Heo   libata: implement...
589
590
  		    tf->nsect == SATA_FPDMA_AA)
  			return 1;
b344991ac   Tejun Heo   libata-acpi: filt...
591
  	}
3264a8d8f   Tejun Heo   libata-acpi: impl...
592
593
  	return 0;
  }
e1ddb4b6a   Alan Cox   [libata] add ACPI...
594
  /**
0e8634bf8   Tejun Heo   libata-acpi: impr...
595
   * ata_acpi_run_tf - send taskfile registers to host controller
3a32a8e96   Tejun Heo   libata-acpi: clea...
596
   * @dev: target ATA device
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
597
598
   * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
   *
3696df309   Sergei Shtylyov   libata: remove AT...
599
   * Outputs ATA taskfile to standard ATA host controller.
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
600
601
602
603
604
605
606
607
608
   * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
   * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
   * hob_lbal, hob_lbam, and hob_lbah.
   *
   * This function waits for idle (!BUSY and !DRQ) after writing
   * registers.  If the control register has a new value, this
   * function also waits for idle after writing control and before
   * writing the remaining registers.
   *
4700c4bc9   Tejun Heo   libata-acpi: clea...
609
610
611
612
   * LOCKING:
   * EH context.
   *
   * RETURNS:
3264a8d8f   Tejun Heo   libata-acpi: impl...
613
614
   * 1 if command is executed successfully.  0 if ignored, rejected or
   * filtered out, -errno on other errors.
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
615
   */
0e8634bf8   Tejun Heo   libata-acpi: impr...
616
  static int ata_acpi_run_tf(struct ata_device *dev,
3264a8d8f   Tejun Heo   libata-acpi: impl...
617
618
  			   const struct ata_acpi_gtf *gtf,
  			   const struct ata_acpi_gtf *prev_gtf)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
619
  {
3264a8d8f   Tejun Heo   libata-acpi: impl...
620
621
  	struct ata_taskfile *pptf = NULL;
  	struct ata_taskfile tf, ptf, rtf;
4700c4bc9   Tejun Heo   libata-acpi: clea...
622
  	unsigned int err_mask;
0e8634bf8   Tejun Heo   libata-acpi: impr...
623
  	const char *level;
6521148c6   Robert Hancock   libata: add comma...
624
  	const char *descr;
0e8634bf8   Tejun Heo   libata-acpi: impr...
625
626
  	char msg[60];
  	int rc;
fc16c25ff   Jeff Garzik   [libata] ACPI: re...
627

4700c4bc9   Tejun Heo   libata-acpi: clea...
628
629
630
631
  	if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0)
  	    && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0)
  	    && (gtf->tf[6] == 0))
  		return 0;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
632

3264a8d8f   Tejun Heo   libata-acpi: impl...
633
634
635
636
637
  	ata_acpi_gtf_to_tf(dev, gtf, &tf);
  	if (prev_gtf) {
  		ata_acpi_gtf_to_tf(dev, prev_gtf, &ptf);
  		pptf = &ptf;
  	}
110f66d25   Tejun Heo   libata: make gtf_...
638
  	if (!ata_acpi_filter_tf(dev, &tf, pptf)) {
3264a8d8f   Tejun Heo   libata-acpi: impl...
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
  		rtf = tf;
  		err_mask = ata_exec_internal(dev, &rtf, NULL,
  					     DMA_NONE, NULL, 0, 0);
  
  		switch (err_mask) {
  		case 0:
  			level = KERN_DEBUG;
  			snprintf(msg, sizeof(msg), "succeeded");
  			rc = 1;
  			break;
  
  		case AC_ERR_DEV:
  			level = KERN_INFO;
  			snprintf(msg, sizeof(msg),
  				 "rejected by device (Stat=0x%02x Err=0x%02x)",
  				 rtf.command, rtf.feature);
  			rc = 0;
  			break;
  
  		default:
  			level = KERN_ERR;
  			snprintf(msg, sizeof(msg),
  				 "failed (Emask=0x%x Stat=0x%02x Err=0x%02x)",
  				 err_mask, rtf.command, rtf.feature);
  			rc = -EIO;
  			break;
  		}
  	} else {
0e8634bf8   Tejun Heo   libata-acpi: impr...
667
  		level = KERN_INFO;
3264a8d8f   Tejun Heo   libata-acpi: impl...
668
  		snprintf(msg, sizeof(msg), "filtered out");
0e8634bf8   Tejun Heo   libata-acpi: impr...
669
  		rc = 0;
4700c4bc9   Tejun Heo   libata-acpi: clea...
670
  	}
6521148c6   Robert Hancock   libata: add comma...
671
  	descr = ata_get_cmd_descript(tf.command);
4700c4bc9   Tejun Heo   libata-acpi: clea...
672

0e8634bf8   Tejun Heo   libata-acpi: impr...
673
  	ata_dev_printk(dev, level,
6521148c6   Robert Hancock   libata: add comma...
674
675
  		       "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x (%s) %s
  ",
0e8634bf8   Tejun Heo   libata-acpi: impr...
676
  		       tf.command, tf.feature, tf.nsect, tf.lbal,
6521148c6   Robert Hancock   libata: add comma...
677
678
  		       tf.lbam, tf.lbah, tf.device,
  		       (descr ? descr : "unknown"), msg);
0e8634bf8   Tejun Heo   libata-acpi: impr...
679
680
  
  	return rc;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
681
682
683
  }
  
  /**
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
684
   * ata_acpi_exec_tfs - get then write drive taskfile settings
6746544c3   Tejun Heo   libata: reimpleme...
685
   * @dev: target ATA device
98a1708de   Martin Olsson   trivial: fix typo...
686
   * @nr_executed: out parameter for the number of executed commands
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
687
   *
98a1708de   Martin Olsson   trivial: fix typo...
688
   * Evaluate _GTF and execute returned taskfiles.
69b16a5f4   Tejun Heo   libata-acpi: misc...
689
690
691
692
693
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
66fa7f215   Tejun Heo   libata-acpi: impr...
694
695
   * Number of executed taskfiles on success, 0 if _GTF doesn't exist.
   * -errno on other errors.
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
696
   */
66fa7f215   Tejun Heo   libata-acpi: impr...
697
  static int ata_acpi_exec_tfs(struct ata_device *dev, int *nr_executed)
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
698
  {
3264a8d8f   Tejun Heo   libata-acpi: impl...
699
  	struct ata_acpi_gtf *gtf = NULL, *pgtf = NULL;
6746544c3   Tejun Heo   libata: reimpleme...
700
701
702
  	int gtf_count, i, rc;
  
  	/* get taskfiles */
66fa7f215   Tejun Heo   libata-acpi: impr...
703
704
705
706
  	rc = ata_dev_get_GTF(dev, &gtf);
  	if (rc < 0)
  		return rc;
  	gtf_count = rc;
6746544c3   Tejun Heo   libata: reimpleme...
707
708
  
  	/* execute them */
3264a8d8f   Tejun Heo   libata-acpi: impl...
709
710
  	for (i = 0; i < gtf_count; i++, gtf++) {
  		rc = ata_acpi_run_tf(dev, gtf, pgtf);
0e8634bf8   Tejun Heo   libata-acpi: impr...
711
712
  		if (rc < 0)
  			break;
3264a8d8f   Tejun Heo   libata-acpi: impl...
713
  		if (rc) {
0e8634bf8   Tejun Heo   libata-acpi: impr...
714
  			(*nr_executed)++;
3264a8d8f   Tejun Heo   libata-acpi: impl...
715
716
  			pgtf = gtf;
  		}
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
717
  	}
398e07826   Tejun Heo   libata-acpi: impl...
718
  	ata_acpi_clear_gtf(dev);
6746544c3   Tejun Heo   libata: reimpleme...
719

0e8634bf8   Tejun Heo   libata-acpi: impr...
720
721
722
  	if (rc < 0)
  		return rc;
  	return 0;
11ef697b3   Kristen Carlson Accardi   [PATCH] libata: A...
723
  }
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
724
725
  /**
   * ata_acpi_push_id - send Identify data to drive
3a32a8e96   Tejun Heo   libata-acpi: clea...
726
   * @dev: target ATA device
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
727
728
729
730
731
732
   *
   * _SDD ACPI object: for SATA mode only
   * Must be after Identify (Packet) Device -- uses its data
   * ATM this function never returns a failure.  It is an optional
   * method and if it fails for whatever reason, we should still
   * just keep going.
69b16a5f4   Tejun Heo   libata-acpi: misc...
733
734
735
736
737
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
f2406770a   Tejun Heo   libata-acpi: miss...
738
   * 0 on success, -ENOENT if _SDD doesn't exist, -errno on failure.
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
739
   */
6746544c3   Tejun Heo   libata: reimpleme...
740
  static int ata_acpi_push_id(struct ata_device *dev)
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
741
  {
9af5c9c97   Tejun Heo   libata-link: intr...
742
  	struct ata_port *ap = dev->link->ap;
3a32a8e96   Tejun Heo   libata-acpi: clea...
743
744
745
  	acpi_status status;
  	struct acpi_object_list input;
  	union acpi_object in_params[1];
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
746

7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
747
  	if (ata_msg_probe(ap))
a9a79dfec   Joe Perches   ata: Convert ata_...
748
749
750
  		ata_dev_dbg(dev, "%s: ix = %d, port#: %d
  ",
  			    __func__, dev->devno, ap->port_no);
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
751

7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
752
753
754
755
756
  	/* Give the drive Identify data to the drive via the _SDD method */
  	/* _SDD: set up input parameters */
  	input.count = 1;
  	input.pointer = in_params;
  	in_params[0].type = ACPI_TYPE_BUFFER;
3a32a8e96   Tejun Heo   libata-acpi: clea...
757
758
  	in_params[0].buffer.length = sizeof(dev->id[0]) * ATA_ID_WORDS;
  	in_params[0].buffer.pointer = (u8 *)dev->id;
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
759
760
761
  	/* Output buffer: _SDD has no output */
  
  	/* It's OK for _SDD to be missing too. */
3a32a8e96   Tejun Heo   libata-acpi: clea...
762
  	swap_buf_le16(dev->id, ATA_ID_WORDS);
30dcf76ac   Matthew Garrett   libata: migrate A...
763
764
  	status = acpi_evaluate_object(ata_dev_acpi_handle(dev), "_SDD", &input,
  				      NULL);
3a32a8e96   Tejun Heo   libata-acpi: clea...
765
  	swap_buf_le16(dev->id, ATA_ID_WORDS);
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
766

f2406770a   Tejun Heo   libata-acpi: miss...
767
768
769
770
  	if (status == AE_NOT_FOUND)
  		return -ENOENT;
  
  	if (ACPI_FAILURE(status)) {
a9a79dfec   Joe Perches   ata: Convert ata_...
771
772
  		ata_dev_warn(dev, "ACPI _SDD failed (AE 0x%x)
  ", status);
f2406770a   Tejun Heo   libata-acpi: miss...
773
774
  		return -EIO;
  	}
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
775

f2406770a   Tejun Heo   libata-acpi: miss...
776
  	return 0;
6746544c3   Tejun Heo   libata: reimpleme...
777
778
779
  }
  
  /**
64578a3de   Tejun Heo   libata-acpi: impl...
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
   * ata_acpi_on_suspend - ATA ACPI hook called on suspend
   * @ap: target ATA port
   *
   * This function is called when @ap is about to be suspended.  All
   * devices are already put to sleep but the port_suspend() callback
   * hasn't been executed yet.  Error return from this function aborts
   * suspend.
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
   * 0 on success, -errno on failure.
   */
  int ata_acpi_on_suspend(struct ata_port *ap)
  {
c05e6ff03   Tejun Heo   libata-acpi: impl...
796
797
  	/* nada */
  	return 0;
64578a3de   Tejun Heo   libata-acpi: impl...
798
799
800
  }
  
  /**
6746544c3   Tejun Heo   libata: reimpleme...
801
802
803
804
805
806
807
808
809
810
811
   * ata_acpi_on_resume - ATA ACPI hook called on resume
   * @ap: target ATA port
   *
   * This function is called when @ap is resumed - right after port
   * itself is resumed but before any EH action is taken.
   *
   * LOCKING:
   * EH context.
   */
  void ata_acpi_on_resume(struct ata_port *ap)
  {
c05e6ff03   Tejun Heo   libata-acpi: impl...
812
  	const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
f58229f80   Tejun Heo   libata-link: impl...
813
  	struct ata_device *dev;
6746544c3   Tejun Heo   libata: reimpleme...
814

f1bc1e4c4   Aaron Lu   ata: acpi: rework...
815
  	if (ACPI_HANDLE(&ap->tdev) && gtm) {
398e07826   Tejun Heo   libata-acpi: impl...
816
817
818
  		/* _GTM valid */
  
  		/* restore timing parameters */
c05e6ff03   Tejun Heo   libata-acpi: impl...
819
  		ata_acpi_stm(ap, gtm);
64578a3de   Tejun Heo   libata-acpi: impl...
820

398e07826   Tejun Heo   libata-acpi: impl...
821
822
823
824
  		/* _GTF should immediately follow _STM so that it can
  		 * use values set by _STM.  Cache _GTF result and
  		 * schedule _GTF.
  		 */
1eca4365b   Tejun Heo   libata: beef up i...
825
  		ata_for_each_dev(dev, &ap->link, ALL) {
398e07826   Tejun Heo   libata-acpi: impl...
826
  			ata_acpi_clear_gtf(dev);
48feb3c41   Shaohua Li   ata-acpi: don't c...
827
  			if (ata_dev_enabled(dev) &&
c75da205e   Aaron Lu   libata: acpi: avo...
828
  			    ata_dev_acpi_handle(dev) &&
48feb3c41   Shaohua Li   ata-acpi: don't c...
829
  			    ata_dev_get_GTF(dev, NULL) >= 0)
398e07826   Tejun Heo   libata-acpi: impl...
830
831
832
833
834
835
836
  				dev->flags |= ATA_DFLAG_ACPI_PENDING;
  		}
  	} else {
  		/* SATA _GTF needs to be evaulated after _SDD and
  		 * there's no reason to evaluate IDE _GTF early
  		 * without _STM.  Clear cache and schedule _GTF.
  		 */
1eca4365b   Tejun Heo   libata: beef up i...
837
  		ata_for_each_dev(dev, &ap->link, ALL) {
398e07826   Tejun Heo   libata-acpi: impl...
838
  			ata_acpi_clear_gtf(dev);
48feb3c41   Shaohua Li   ata-acpi: don't c...
839
840
  			if (ata_dev_enabled(dev))
  				dev->flags |= ATA_DFLAG_ACPI_PENDING;
398e07826   Tejun Heo   libata-acpi: impl...
841
842
  		}
  	}
7ea1fbc2a   Kristen Carlson Accardi   [PATCH] libata: A...
843
  }
a7ff60dbe   Aaron Lu   [libata] pm: diff...
844
  static int ata_acpi_choose_suspend_state(struct ata_device *dev, bool runtime)
213342053   Aaron Lu   libata: handle po...
845
846
  {
  	int d_max_in = ACPI_STATE_D3_COLD;
a7ff60dbe   Aaron Lu   [libata] pm: diff...
847
848
  	if (!runtime)
  		goto out;
213342053   Aaron Lu   libata: handle po...
849
850
851
852
853
854
855
856
  
  	/*
  	 * For ATAPI, runtime D3 cold is only allowed
  	 * for ZPODD in zero power ready state
  	 */
  	if (dev->class == ATA_DEV_ATAPI &&
  	    !(zpodd_dev_enabled(dev) && zpodd_zpready(dev)))
  		d_max_in = ACPI_STATE_D3_HOT;
a7ff60dbe   Aaron Lu   [libata] pm: diff...
857
  out:
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
858
  	return acpi_pm_device_sleep_state(&dev->tdev, NULL, d_max_in);
213342053   Aaron Lu   libata: handle po...
859
  }
a7ff60dbe   Aaron Lu   [libata] pm: diff...
860
  static void sata_acpi_set_state(struct ata_port *ap, pm_message_t state)
bd3adca52   Shaohua Li   libata-acpi: add ...
861
  {
a7ff60dbe   Aaron Lu   [libata] pm: diff...
862
  	bool runtime = PMSG_IS_AUTO(state);
bd3adca52   Shaohua Li   libata-acpi: add ...
863
  	struct ata_device *dev;
febe53ba6   Lin Ming   libata-acpi: set ...
864
  	acpi_handle handle;
3bd46600a   Lin Ming   libata-acpi: add ...
865
  	int acpi_state;
bd3adca52   Shaohua Li   libata-acpi: add ...
866

1eca4365b   Tejun Heo   libata: beef up i...
867
  	ata_for_each_dev(dev, &ap->link, ENABLED) {
febe53ba6   Lin Ming   libata-acpi: set ...
868
  		handle = ata_dev_acpi_handle(dev);
3bd46600a   Lin Ming   libata-acpi: add ...
869
870
  		if (!handle)
  			continue;
a7ff60dbe   Aaron Lu   [libata] pm: diff...
871
872
  		if (!(state.event & PM_EVENT_RESUME)) {
  			acpi_state = ata_acpi_choose_suspend_state(dev, runtime);
213342053   Aaron Lu   libata: handle po...
873
874
  			if (acpi_state == ACPI_STATE_D0)
  				continue;
a7ff60dbe   Aaron Lu   [libata] pm: diff...
875
  			if (runtime && zpodd_dev_enabled(dev) &&
213342053   Aaron Lu   libata: handle po...
876
877
878
  			    acpi_state == ACPI_STATE_D3_COLD)
  				zpodd_enable_run_wake(dev);
  			acpi_bus_set_power(handle, acpi_state);
3bd46600a   Lin Ming   libata-acpi: add ...
879
  		} else {
a7ff60dbe   Aaron Lu   [libata] pm: diff...
880
  			if (runtime && zpodd_dev_enabled(dev))
213342053   Aaron Lu   libata: handle po...
881
  				zpodd_disable_run_wake(dev);
3bd46600a   Lin Ming   libata-acpi: add ...
882
883
  			acpi_bus_set_power(handle, ACPI_STATE_D0);
  		}
bd3adca52   Shaohua Li   libata-acpi: add ...
884
  	}
a7ff60dbe   Aaron Lu   [libata] pm: diff...
885
  }
febe53ba6   Lin Ming   libata-acpi: set ...
886

a7ff60dbe   Aaron Lu   [libata] pm: diff...
887
888
889
890
891
  /* ACPI spec requires _PS0 when IDE power on and _PS3 when power off */
  static void pata_acpi_set_state(struct ata_port *ap, pm_message_t state)
  {
  	struct ata_device *dev;
  	acpi_handle port_handle;
f1bc1e4c4   Aaron Lu   ata: acpi: rework...
892
  	port_handle = ACPI_HANDLE(&ap->tdev);
a7ff60dbe   Aaron Lu   [libata] pm: diff...
893
894
895
896
897
898
899
  	if (!port_handle)
  		return;
  
  	/* channel first and then drives for power on and vica versa
  	   for power off */
  	if (state.event & PM_EVENT_RESUME)
  		acpi_bus_set_power(port_handle, ACPI_STATE_D0);
febe53ba6   Lin Ming   libata-acpi: set ...
900

a7ff60dbe   Aaron Lu   [libata] pm: diff...
901
902
903
904
905
906
  	ata_for_each_dev(dev, &ap->link, ENABLED) {
  		acpi_handle dev_handle = ata_dev_acpi_handle(dev);
  		if (!dev_handle)
  			continue;
  
  		acpi_bus_set_power(dev_handle, state.event & PM_EVENT_RESUME ?
8ad928d52   Rafael J. Wysocki   ACPI / PM: Use AC...
907
  					ACPI_STATE_D0 : ACPI_STATE_D3_COLD);
a7ff60dbe   Aaron Lu   [libata] pm: diff...
908
909
910
  	}
  
  	if (!(state.event & PM_EVENT_RESUME))
8ad928d52   Rafael J. Wysocki   ACPI / PM: Use AC...
911
  		acpi_bus_set_power(port_handle, ACPI_STATE_D3_COLD);
a7ff60dbe   Aaron Lu   [libata] pm: diff...
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
  }
  
  /**
   * ata_acpi_set_state - set the port power state
   * @ap: target ATA port
   * @state: state, on/off
   *
   * This function sets a proper ACPI D state for the device on
   * system and runtime PM operations.
   */
  void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
  {
  	if (ap->flags & ATA_FLAG_ACPI_SATA)
  		sata_acpi_set_state(ap, state);
  	else
  		pata_acpi_set_state(ap, state);
bd3adca52   Shaohua Li   libata-acpi: add ...
928
929
930
  }
  
  /**
6746544c3   Tejun Heo   libata: reimpleme...
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
   * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration
   * @dev: target ATA device
   *
   * This function is called when @dev is about to be configured.
   * IDENTIFY data might have been modified after this hook is run.
   *
   * LOCKING:
   * EH context.
   *
   * RETURNS:
   * Positive number if IDENTIFY data needs to be refreshed, 0 if not,
   * -errno on failure.
   */
  int ata_acpi_on_devcfg(struct ata_device *dev)
  {
9af5c9c97   Tejun Heo   libata-link: intr...
946
947
  	struct ata_port *ap = dev->link->ap;
  	struct ata_eh_context *ehc = &ap->link.eh_context;
6746544c3   Tejun Heo   libata: reimpleme...
948
  	int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA;
66fa7f215   Tejun Heo   libata-acpi: impr...
949
  	int nr_executed = 0;
6746544c3   Tejun Heo   libata: reimpleme...
950
  	int rc;
30dcf76ac   Matthew Garrett   libata: migrate A...
951
  	if (!ata_dev_acpi_handle(dev))
6746544c3   Tejun Heo   libata: reimpleme...
952
953
954
955
956
957
958
959
960
961
  		return 0;
  
  	/* do we need to do _GTF? */
  	if (!(dev->flags & ATA_DFLAG_ACPI_PENDING) &&
  	    !(acpi_sata && (ehc->i.flags & ATA_EHI_DID_HARDRESET)))
  		return 0;
  
  	/* do _SDD if SATA */
  	if (acpi_sata) {
  		rc = ata_acpi_push_id(dev);
f2406770a   Tejun Heo   libata-acpi: miss...
962
  		if (rc && rc != -ENOENT)
6746544c3   Tejun Heo   libata: reimpleme...
963
964
965
966
  			goto acpi_err;
  	}
  
  	/* do _GTF */
66fa7f215   Tejun Heo   libata-acpi: impr...
967
968
  	rc = ata_acpi_exec_tfs(dev, &nr_executed);
  	if (rc)
6746544c3   Tejun Heo   libata: reimpleme...
969
970
971
972
973
  		goto acpi_err;
  
  	dev->flags &= ~ATA_DFLAG_ACPI_PENDING;
  
  	/* refresh IDENTIFY page if any _GTF command has been executed */
66fa7f215   Tejun Heo   libata-acpi: impr...
974
  	if (nr_executed) {
6746544c3   Tejun Heo   libata: reimpleme...
975
976
  		rc = ata_dev_reread_id(dev, 0);
  		if (rc < 0) {
a9a79dfec   Joe Perches   ata: Convert ata_...
977
978
979
  			ata_dev_err(dev,
  				    "failed to IDENTIFY after ACPI commands
  ");
6746544c3   Tejun Heo   libata: reimpleme...
980
981
982
983
984
985
986
  			return rc;
  		}
  	}
  
  	return 0;
  
   acpi_err:
66fa7f215   Tejun Heo   libata-acpi: impr...
987
988
989
  	/* ignore evaluation failure if we can continue safely */
  	if (rc == -EINVAL && !nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN))
  		return 0;
6746544c3   Tejun Heo   libata: reimpleme...
990

66fa7f215   Tejun Heo   libata-acpi: impr...
991
992
993
994
  	/* fail and let EH retry once more for unknown IO errors */
  	if (!(dev->flags & ATA_DFLAG_ACPI_FAILED)) {
  		dev->flags |= ATA_DFLAG_ACPI_FAILED;
  		return rc;
6746544c3   Tejun Heo   libata: reimpleme...
995
  	}
66fa7f215   Tejun Heo   libata-acpi: impr...
996

0d0cdb028   Aaron Lu   libata: restore a...
997
  	dev->flags |= ATA_DFLAG_ACPI_DISABLED;
a9a79dfec   Joe Perches   ata: Convert ata_...
998
999
  	ata_dev_warn(dev, "ACPI: failed the second time, disabled
  ");
66fa7f215   Tejun Heo   libata-acpi: impr...
1000
1001
1002
1003
1004
1005
  
  	/* We can safely continue if no _GTF command has been executed
  	 * and port is not frozen.
  	 */
  	if (!nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN))
  		return 0;
6746544c3   Tejun Heo   libata: reimpleme...
1006
1007
  	return rc;
  }
562f0c2d7   Tejun Heo   libata-acpi: add ...
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
  
  /**
   * ata_acpi_on_disable - ATA ACPI hook called when a device is disabled
   * @dev: target ATA device
   *
   * This function is called when @dev is about to be disabled.
   *
   * LOCKING:
   * EH context.
   */
  void ata_acpi_on_disable(struct ata_device *dev)
  {
398e07826   Tejun Heo   libata-acpi: impl...
1020
  	ata_acpi_clear_gtf(dev);
562f0c2d7   Tejun Heo   libata-acpi: add ...
1021
  }