]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - drivers/ata/libata-sata.c
d66afdc33d54dd326a7b498660f576e7a4d5ccfd
[mirror_ubuntu-jammy-kernel.git] / drivers / ata / libata-sata.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * SATA specific part of ATA helper library
4 *
5 * Copyright 2003-2004 Red Hat, Inc. All rights reserved.
6 * Copyright 2003-2004 Jeff Garzik
7 */
8
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/libata.h>
12
13 #include "libata.h"
14
15 /**
16 * sata_scr_valid - test whether SCRs are accessible
17 * @link: ATA link to test SCR accessibility for
18 *
19 * Test whether SCRs are accessible for @link.
20 *
21 * LOCKING:
22 * None.
23 *
24 * RETURNS:
25 * 1 if SCRs are accessible, 0 otherwise.
26 */
27 int sata_scr_valid(struct ata_link *link)
28 {
29 struct ata_port *ap = link->ap;
30
31 return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read;
32 }
33 EXPORT_SYMBOL_GPL(sata_scr_valid);
34
35 /**
36 * sata_scr_read - read SCR register of the specified port
37 * @link: ATA link to read SCR for
38 * @reg: SCR to read
39 * @val: Place to store read value
40 *
41 * Read SCR register @reg of @link into *@val. This function is
42 * guaranteed to succeed if @link is ap->link, the cable type of
43 * the port is SATA and the port implements ->scr_read.
44 *
45 * LOCKING:
46 * None if @link is ap->link. Kernel thread context otherwise.
47 *
48 * RETURNS:
49 * 0 on success, negative errno on failure.
50 */
51 int sata_scr_read(struct ata_link *link, int reg, u32 *val)
52 {
53 if (ata_is_host_link(link)) {
54 if (sata_scr_valid(link))
55 return link->ap->ops->scr_read(link, reg, val);
56 return -EOPNOTSUPP;
57 }
58
59 return sata_pmp_scr_read(link, reg, val);
60 }
61 EXPORT_SYMBOL_GPL(sata_scr_read);
62
63 /**
64 * sata_scr_write - write SCR register of the specified port
65 * @link: ATA link to write SCR for
66 * @reg: SCR to write
67 * @val: value to write
68 *
69 * Write @val to SCR register @reg of @link. This function is
70 * guaranteed to succeed if @link is ap->link, the cable type of
71 * the port is SATA and the port implements ->scr_read.
72 *
73 * LOCKING:
74 * None if @link is ap->link. Kernel thread context otherwise.
75 *
76 * RETURNS:
77 * 0 on success, negative errno on failure.
78 */
79 int sata_scr_write(struct ata_link *link, int reg, u32 val)
80 {
81 if (ata_is_host_link(link)) {
82 if (sata_scr_valid(link))
83 return link->ap->ops->scr_write(link, reg, val);
84 return -EOPNOTSUPP;
85 }
86
87 return sata_pmp_scr_write(link, reg, val);
88 }
89 EXPORT_SYMBOL_GPL(sata_scr_write);
90
91 /**
92 * sata_scr_write_flush - write SCR register of the specified port and flush
93 * @link: ATA link to write SCR for
94 * @reg: SCR to write
95 * @val: value to write
96 *
97 * This function is identical to sata_scr_write() except that this
98 * function performs flush after writing to the register.
99 *
100 * LOCKING:
101 * None if @link is ap->link. Kernel thread context otherwise.
102 *
103 * RETURNS:
104 * 0 on success, negative errno on failure.
105 */
106 int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
107 {
108 if (ata_is_host_link(link)) {
109 int rc;
110
111 if (sata_scr_valid(link)) {
112 rc = link->ap->ops->scr_write(link, reg, val);
113 if (rc == 0)
114 rc = link->ap->ops->scr_read(link, reg, &val);
115 return rc;
116 }
117 return -EOPNOTSUPP;
118 }
119
120 return sata_pmp_scr_write(link, reg, val);
121 }
122 EXPORT_SYMBOL_GPL(sata_scr_write_flush);
123
124 /**
125 * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
126 * @tf: Taskfile to convert
127 * @pmp: Port multiplier port
128 * @is_cmd: This FIS is for command
129 * @fis: Buffer into which data will output
130 *
131 * Converts a standard ATA taskfile to a Serial ATA
132 * FIS structure (Register - Host to Device).
133 *
134 * LOCKING:
135 * Inherited from caller.
136 */
137 void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis)
138 {
139 fis[0] = 0x27; /* Register - Host to Device FIS */
140 fis[1] = pmp & 0xf; /* Port multiplier number*/
141 if (is_cmd)
142 fis[1] |= (1 << 7); /* bit 7 indicates Command FIS */
143
144 fis[2] = tf->command;
145 fis[3] = tf->feature;
146
147 fis[4] = tf->lbal;
148 fis[5] = tf->lbam;
149 fis[6] = tf->lbah;
150 fis[7] = tf->device;
151
152 fis[8] = tf->hob_lbal;
153 fis[9] = tf->hob_lbam;
154 fis[10] = tf->hob_lbah;
155 fis[11] = tf->hob_feature;
156
157 fis[12] = tf->nsect;
158 fis[13] = tf->hob_nsect;
159 fis[14] = 0;
160 fis[15] = tf->ctl;
161
162 fis[16] = tf->auxiliary & 0xff;
163 fis[17] = (tf->auxiliary >> 8) & 0xff;
164 fis[18] = (tf->auxiliary >> 16) & 0xff;
165 fis[19] = (tf->auxiliary >> 24) & 0xff;
166 }
167 EXPORT_SYMBOL_GPL(ata_tf_to_fis);
168
169 /**
170 * ata_tf_from_fis - Convert SATA FIS to ATA taskfile
171 * @fis: Buffer from which data will be input
172 * @tf: Taskfile to output
173 *
174 * Converts a serial ATA FIS structure to a standard ATA taskfile.
175 *
176 * LOCKING:
177 * Inherited from caller.
178 */
179
180 void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
181 {
182 tf->command = fis[2]; /* status */
183 tf->feature = fis[3]; /* error */
184
185 tf->lbal = fis[4];
186 tf->lbam = fis[5];
187 tf->lbah = fis[6];
188 tf->device = fis[7];
189
190 tf->hob_lbal = fis[8];
191 tf->hob_lbam = fis[9];
192 tf->hob_lbah = fis[10];
193
194 tf->nsect = fis[12];
195 tf->hob_nsect = fis[13];
196 }
197 EXPORT_SYMBOL_GPL(ata_tf_from_fis);
198
199 /**
200 * sata_link_scr_lpm - manipulate SControl IPM and SPM fields
201 * @link: ATA link to manipulate SControl for
202 * @policy: LPM policy to configure
203 * @spm_wakeup: initiate LPM transition to active state
204 *
205 * Manipulate the IPM field of the SControl register of @link
206 * according to @policy. If @policy is ATA_LPM_MAX_POWER and
207 * @spm_wakeup is %true, the SPM field is manipulated to wake up
208 * the link. This function also clears PHYRDY_CHG before
209 * returning.
210 *
211 * LOCKING:
212 * EH context.
213 *
214 * RETURNS:
215 * 0 on success, -errno otherwise.
216 */
217 int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
218 bool spm_wakeup)
219 {
220 struct ata_eh_context *ehc = &link->eh_context;
221 bool woken_up = false;
222 u32 scontrol;
223 int rc;
224
225 rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
226 if (rc)
227 return rc;
228
229 switch (policy) {
230 case ATA_LPM_MAX_POWER:
231 /* disable all LPM transitions */
232 scontrol |= (0x7 << 8);
233 /* initiate transition to active state */
234 if (spm_wakeup) {
235 scontrol |= (0x4 << 12);
236 woken_up = true;
237 }
238 break;
239 case ATA_LPM_MED_POWER:
240 /* allow LPM to PARTIAL */
241 scontrol &= ~(0x1 << 8);
242 scontrol |= (0x6 << 8);
243 break;
244 case ATA_LPM_MED_POWER_WITH_DIPM:
245 case ATA_LPM_MIN_POWER_WITH_PARTIAL:
246 case ATA_LPM_MIN_POWER:
247 if (ata_link_nr_enabled(link) > 0)
248 /* no restrictions on LPM transitions */
249 scontrol &= ~(0x7 << 8);
250 else {
251 /* empty port, power off */
252 scontrol &= ~0xf;
253 scontrol |= (0x1 << 2);
254 }
255 break;
256 default:
257 WARN_ON(1);
258 }
259
260 rc = sata_scr_write(link, SCR_CONTROL, scontrol);
261 if (rc)
262 return rc;
263
264 /* give the link time to transit out of LPM state */
265 if (woken_up)
266 msleep(10);
267
268 /* clear PHYRDY_CHG from SError */
269 ehc->i.serror &= ~SERR_PHYRDY_CHG;
270 return sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG);
271 }
272 EXPORT_SYMBOL_GPL(sata_link_scr_lpm);
273
274 static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol)
275 {
276 struct ata_link *host_link = &link->ap->link;
277 u32 limit, target, spd;
278
279 limit = link->sata_spd_limit;
280
281 /* Don't configure downstream link faster than upstream link.
282 * It doesn't speed up anything and some PMPs choke on such
283 * configuration.
284 */
285 if (!ata_is_host_link(link) && host_link->sata_spd)
286 limit &= (1 << host_link->sata_spd) - 1;
287
288 if (limit == UINT_MAX)
289 target = 0;
290 else
291 target = fls(limit);
292
293 spd = (*scontrol >> 4) & 0xf;
294 *scontrol = (*scontrol & ~0xf0) | ((target & 0xf) << 4);
295
296 return spd != target;
297 }
298
299 /**
300 * sata_set_spd_needed - is SATA spd configuration needed
301 * @link: Link in question
302 *
303 * Test whether the spd limit in SControl matches
304 * @link->sata_spd_limit. This function is used to determine
305 * whether hardreset is necessary to apply SATA spd
306 * configuration.
307 *
308 * LOCKING:
309 * Inherited from caller.
310 *
311 * RETURNS:
312 * 1 if SATA spd configuration is needed, 0 otherwise.
313 */
314 int sata_set_spd_needed(struct ata_link *link)
315 {
316 u32 scontrol;
317
318 if (sata_scr_read(link, SCR_CONTROL, &scontrol))
319 return 1;
320
321 return __sata_set_spd_needed(link, &scontrol);
322 }
323
324 /**
325 * sata_set_spd - set SATA spd according to spd limit
326 * @link: Link to set SATA spd for
327 *
328 * Set SATA spd of @link according to sata_spd_limit.
329 *
330 * LOCKING:
331 * Inherited from caller.
332 *
333 * RETURNS:
334 * 0 if spd doesn't need to be changed, 1 if spd has been
335 * changed. Negative errno if SCR registers are inaccessible.
336 */
337 int sata_set_spd(struct ata_link *link)
338 {
339 u32 scontrol;
340 int rc;
341
342 if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
343 return rc;
344
345 if (!__sata_set_spd_needed(link, &scontrol))
346 return 0;
347
348 if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol)))
349 return rc;
350
351 return 1;
352 }
353 EXPORT_SYMBOL_GPL(sata_set_spd);
354
355 /**
356 * ata_slave_link_init - initialize slave link
357 * @ap: port to initialize slave link for
358 *
359 * Create and initialize slave link for @ap. This enables slave
360 * link handling on the port.
361 *
362 * In libata, a port contains links and a link contains devices.
363 * There is single host link but if a PMP is attached to it,
364 * there can be multiple fan-out links. On SATA, there's usually
365 * a single device connected to a link but PATA and SATA
366 * controllers emulating TF based interface can have two - master
367 * and slave.
368 *
369 * However, there are a few controllers which don't fit into this
370 * abstraction too well - SATA controllers which emulate TF
371 * interface with both master and slave devices but also have
372 * separate SCR register sets for each device. These controllers
373 * need separate links for physical link handling
374 * (e.g. onlineness, link speed) but should be treated like a
375 * traditional M/S controller for everything else (e.g. command
376 * issue, softreset).
377 *
378 * slave_link is libata's way of handling this class of
379 * controllers without impacting core layer too much. For
380 * anything other than physical link handling, the default host
381 * link is used for both master and slave. For physical link
382 * handling, separate @ap->slave_link is used. All dirty details
383 * are implemented inside libata core layer. From LLD's POV, the
384 * only difference is that prereset, hardreset and postreset are
385 * called once more for the slave link, so the reset sequence
386 * looks like the following.
387 *
388 * prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
389 * softreset(M) -> postreset(M) -> postreset(S)
390 *
391 * Note that softreset is called only for the master. Softreset
392 * resets both M/S by definition, so SRST on master should handle
393 * both (the standard method will work just fine).
394 *
395 * LOCKING:
396 * Should be called before host is registered.
397 *
398 * RETURNS:
399 * 0 on success, -errno on failure.
400 */
401 int ata_slave_link_init(struct ata_port *ap)
402 {
403 struct ata_link *link;
404
405 WARN_ON(ap->slave_link);
406 WARN_ON(ap->flags & ATA_FLAG_PMP);
407
408 link = kzalloc(sizeof(*link), GFP_KERNEL);
409 if (!link)
410 return -ENOMEM;
411
412 ata_link_init(ap, link, 1);
413 ap->slave_link = link;
414 return 0;
415 }
416 EXPORT_SYMBOL_GPL(ata_slave_link_init);
417
418 /**
419 * sata_lpm_ignore_phy_events - test if PHY event should be ignored
420 * @link: Link receiving the event
421 *
422 * Test whether the received PHY event has to be ignored or not.
423 *
424 * LOCKING:
425 * None:
426 *
427 * RETURNS:
428 * True if the event has to be ignored.
429 */
430 bool sata_lpm_ignore_phy_events(struct ata_link *link)
431 {
432 unsigned long lpm_timeout = link->last_lpm_change +
433 msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY);
434
435 /* if LPM is enabled, PHYRDY doesn't mean anything */
436 if (link->lpm_policy > ATA_LPM_MAX_POWER)
437 return true;
438
439 /* ignore the first PHY event after the LPM policy changed
440 * as it is might be spurious
441 */
442 if ((link->flags & ATA_LFLAG_CHANGED) &&
443 time_before(jiffies, lpm_timeout))
444 return true;
445
446 return false;
447 }
448 EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events);