1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * libata-pmp.c - libata port multiplier support |
4 | * |
5 | * Copyright (c) 2007 SUSE Linux Products GmbH |
6 | * Copyright (c) 2007 Tejun Heo <teheo@suse.de> |
7 | */ |
8 | |
9 | #include <linux/kernel.h> |
10 | #include <linux/export.h> |
11 | #include <linux/libata.h> |
12 | #include <linux/slab.h> |
13 | #include "libata.h" |
14 | #include "libata-transport.h" |
15 | |
16 | const struct ata_port_operations sata_pmp_port_ops = { |
17 | .inherits = &sata_port_ops, |
18 | .pmp_prereset = ata_std_prereset, |
19 | .pmp_hardreset = sata_std_hardreset, |
20 | .pmp_postreset = ata_std_postreset, |
21 | .error_handler = sata_pmp_error_handler, |
22 | }; |
23 | |
24 | /** |
25 | * sata_pmp_read - read PMP register |
26 | * @link: link to read PMP register for |
27 | * @reg: register to read |
28 | * @r_val: resulting value |
29 | * |
30 | * Read PMP register. |
31 | * |
32 | * LOCKING: |
33 | * Kernel thread context (may sleep). |
34 | * |
35 | * RETURNS: |
36 | * 0 on success, AC_ERR_* mask on failure. |
37 | */ |
38 | static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) |
39 | { |
40 | struct ata_port *ap = link->ap; |
41 | struct ata_device *pmp_dev = ap->link.device; |
42 | struct ata_taskfile tf; |
43 | unsigned int err_mask; |
44 | |
45 | ata_tf_init(dev: pmp_dev, tf: &tf); |
46 | tf.command = ATA_CMD_PMP_READ; |
47 | tf.protocol = ATA_PROT_NODATA; |
48 | tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48; |
49 | tf.feature = reg; |
50 | tf.device = link->pmp; |
51 | |
52 | err_mask = ata_exec_internal(dev: pmp_dev, tf: &tf, NULL, dma_dir: DMA_NONE, NULL, buflen: 0, |
53 | timeout: SATA_PMP_RW_TIMEOUT); |
54 | if (err_mask) |
55 | return err_mask; |
56 | |
57 | *r_val = tf.nsect | tf.lbal << 8 | tf.lbam << 16 | tf.lbah << 24; |
58 | return 0; |
59 | } |
60 | |
61 | /** |
62 | * sata_pmp_write - write PMP register |
63 | * @link: link to write PMP register for |
64 | * @reg: register to write |
65 | * @val: value to write |
66 | * |
67 | * Write PMP register. |
68 | * |
69 | * LOCKING: |
70 | * Kernel thread context (may sleep). |
71 | * |
72 | * RETURNS: |
73 | * 0 on success, AC_ERR_* mask on failure. |
74 | */ |
75 | static unsigned int sata_pmp_write(struct ata_link *link, int reg, u32 val) |
76 | { |
77 | struct ata_port *ap = link->ap; |
78 | struct ata_device *pmp_dev = ap->link.device; |
79 | struct ata_taskfile tf; |
80 | |
81 | ata_tf_init(dev: pmp_dev, tf: &tf); |
82 | tf.command = ATA_CMD_PMP_WRITE; |
83 | tf.protocol = ATA_PROT_NODATA; |
84 | tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48; |
85 | tf.feature = reg; |
86 | tf.device = link->pmp; |
87 | tf.nsect = val & 0xff; |
88 | tf.lbal = (val >> 8) & 0xff; |
89 | tf.lbam = (val >> 16) & 0xff; |
90 | tf.lbah = (val >> 24) & 0xff; |
91 | |
92 | return ata_exec_internal(dev: pmp_dev, tf: &tf, NULL, dma_dir: DMA_NONE, NULL, buflen: 0, |
93 | timeout: SATA_PMP_RW_TIMEOUT); |
94 | } |
95 | |
96 | /** |
97 | * sata_pmp_qc_defer_cmd_switch - qc_defer for command switching PMP |
98 | * @qc: ATA command in question |
99 | * |
100 | * A host which has command switching PMP support cannot issue |
101 | * commands to multiple links simultaneously. |
102 | * |
103 | * LOCKING: |
104 | * spin_lock_irqsave(host lock) |
105 | * |
106 | * RETURNS: |
107 | * ATA_DEFER_* if deferring is needed, 0 otherwise. |
108 | */ |
109 | int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc) |
110 | { |
111 | struct ata_link *link = qc->dev->link; |
112 | struct ata_port *ap = link->ap; |
113 | |
114 | if (ap->excl_link == NULL || ap->excl_link == link) { |
115 | if (ap->nr_active_links == 0 || ata_link_active(link)) { |
116 | qc->flags |= ATA_QCFLAG_CLEAR_EXCL; |
117 | return ata_std_qc_defer(qc); |
118 | } |
119 | |
120 | ap->excl_link = link; |
121 | } |
122 | |
123 | return ATA_DEFER_PORT; |
124 | } |
125 | |
126 | /** |
127 | * sata_pmp_scr_read - read PSCR |
128 | * @link: ATA link to read PSCR for |
129 | * @reg: PSCR to read |
130 | * @r_val: resulting value |
131 | * |
132 | * Read PSCR @reg into @r_val for @link, to be called from |
133 | * ata_scr_read(). |
134 | * |
135 | * LOCKING: |
136 | * Kernel thread context (may sleep). |
137 | * |
138 | * RETURNS: |
139 | * 0 on success, -errno on failure. |
140 | */ |
141 | int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *r_val) |
142 | { |
143 | unsigned int err_mask; |
144 | |
145 | if (reg > SATA_PMP_PSCR_CONTROL) |
146 | return -EINVAL; |
147 | |
148 | err_mask = sata_pmp_read(link, reg, r_val); |
149 | if (err_mask) { |
150 | ata_link_warn(link, "failed to read SCR %d (Emask=0x%x)\n" , |
151 | reg, err_mask); |
152 | return -EIO; |
153 | } |
154 | return 0; |
155 | } |
156 | |
157 | /** |
158 | * sata_pmp_scr_write - write PSCR |
159 | * @link: ATA link to write PSCR for |
160 | * @reg: PSCR to write |
161 | * @val: value to be written |
162 | * |
163 | * Write @val to PSCR @reg for @link, to be called from |
164 | * ata_scr_write() and ata_scr_write_flush(). |
165 | * |
166 | * LOCKING: |
167 | * Kernel thread context (may sleep). |
168 | * |
169 | * RETURNS: |
170 | * 0 on success, -errno on failure. |
171 | */ |
172 | int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val) |
173 | { |
174 | unsigned int err_mask; |
175 | |
176 | if (reg > SATA_PMP_PSCR_CONTROL) |
177 | return -EINVAL; |
178 | |
179 | err_mask = sata_pmp_write(link, reg, val); |
180 | if (err_mask) { |
181 | ata_link_warn(link, "failed to write SCR %d (Emask=0x%x)\n" , |
182 | reg, err_mask); |
183 | return -EIO; |
184 | } |
185 | return 0; |
186 | } |
187 | |
188 | /** |
189 | * sata_pmp_set_lpm - configure LPM for a PMP link |
190 | * @link: PMP link to configure LPM for |
191 | * @policy: target LPM policy |
192 | * @hints: LPM hints |
193 | * |
194 | * Configure LPM for @link. This function will contain any PMP |
195 | * specific workarounds if necessary. |
196 | * |
197 | * LOCKING: |
198 | * EH context. |
199 | * |
200 | * RETURNS: |
201 | * 0 on success, -errno on failure. |
202 | */ |
203 | int sata_pmp_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, |
204 | unsigned hints) |
205 | { |
206 | return sata_link_scr_lpm(link, policy, spm_wakeup: true); |
207 | } |
208 | |
209 | /** |
210 | * sata_pmp_read_gscr - read GSCR block of SATA PMP |
211 | * @dev: PMP device |
212 | * @gscr: buffer to read GSCR block into |
213 | * |
214 | * Read selected PMP GSCRs from the PMP at @dev. This will serve |
215 | * as configuration and identification info for the PMP. |
216 | * |
217 | * LOCKING: |
218 | * Kernel thread context (may sleep). |
219 | * |
220 | * RETURNS: |
221 | * 0 on success, -errno on failure. |
222 | */ |
223 | static int sata_pmp_read_gscr(struct ata_device *dev, u32 *gscr) |
224 | { |
225 | static const int gscr_to_read[] = { 0, 1, 2, 32, 33, 64, 96 }; |
226 | int i; |
227 | |
228 | for (i = 0; i < ARRAY_SIZE(gscr_to_read); i++) { |
229 | int reg = gscr_to_read[i]; |
230 | unsigned int err_mask; |
231 | |
232 | err_mask = sata_pmp_read(link: dev->link, reg, r_val: &gscr[reg]); |
233 | if (err_mask) { |
234 | ata_dev_err(dev, "failed to read PMP GSCR[%d] (Emask=0x%x)\n" , |
235 | reg, err_mask); |
236 | return -EIO; |
237 | } |
238 | } |
239 | |
240 | return 0; |
241 | } |
242 | |
243 | static const char *sata_pmp_spec_rev_str(const u32 *gscr) |
244 | { |
245 | u32 rev = gscr[SATA_PMP_GSCR_REV]; |
246 | |
247 | if (rev & (1 << 3)) |
248 | return "1.2" ; |
249 | if (rev & (1 << 2)) |
250 | return "1.1" ; |
251 | if (rev & (1 << 1)) |
252 | return "1.0" ; |
253 | return "<unknown>" ; |
254 | } |
255 | |
256 | #define PMP_GSCR_SII_POL 129 |
257 | |
258 | static int sata_pmp_configure(struct ata_device *dev, int print_info) |
259 | { |
260 | struct ata_port *ap = dev->link->ap; |
261 | u32 *gscr = dev->gscr; |
262 | u16 vendor = sata_pmp_gscr_vendor(gscr); |
263 | u16 devid = sata_pmp_gscr_devid(gscr); |
264 | unsigned int err_mask = 0; |
265 | const char *reason; |
266 | int nr_ports, rc; |
267 | |
268 | nr_ports = sata_pmp_gscr_ports(gscr); |
269 | |
270 | if (nr_ports <= 0 || nr_ports > SATA_PMP_MAX_PORTS) { |
271 | rc = -EINVAL; |
272 | reason = "invalid nr_ports" ; |
273 | goto fail; |
274 | } |
275 | |
276 | if ((ap->flags & ATA_FLAG_AN) && |
277 | (gscr[SATA_PMP_GSCR_FEAT] & SATA_PMP_FEAT_NOTIFY)) |
278 | dev->flags |= ATA_DFLAG_AN; |
279 | |
280 | /* monitor SERR_PHYRDY_CHG on fan-out ports */ |
281 | err_mask = sata_pmp_write(link: dev->link, reg: SATA_PMP_GSCR_ERROR_EN, |
282 | val: SERR_PHYRDY_CHG); |
283 | if (err_mask) { |
284 | rc = -EIO; |
285 | reason = "failed to write GSCR_ERROR_EN" ; |
286 | goto fail; |
287 | } |
288 | |
289 | /* Disable sending Early R_OK. |
290 | * With "cached read" HDD testing and multiple ports busy on a SATA |
291 | * host controller, 3x26 PMP will very rarely drop a deferred |
292 | * R_OK that was intended for the host. Symptom will be all |
293 | * 5 drives under test will timeout, get reset, and recover. |
294 | */ |
295 | if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) { |
296 | u32 reg; |
297 | |
298 | err_mask = sata_pmp_read(link: &ap->link, PMP_GSCR_SII_POL, r_val: ®); |
299 | if (err_mask) { |
300 | rc = -EIO; |
301 | reason = "failed to read Sil3x26 Private Register" ; |
302 | goto fail; |
303 | } |
304 | reg &= ~0x1; |
305 | err_mask = sata_pmp_write(link: &ap->link, PMP_GSCR_SII_POL, val: reg); |
306 | if (err_mask) { |
307 | rc = -EIO; |
308 | reason = "failed to write Sil3x26 Private Register" ; |
309 | goto fail; |
310 | } |
311 | } |
312 | |
313 | if (print_info) { |
314 | ata_dev_info(dev, "Port Multiplier %s, " |
315 | "0x%04x:0x%04x r%d, %d ports, feat 0x%x/0x%x\n" , |
316 | sata_pmp_spec_rev_str(gscr), vendor, devid, |
317 | sata_pmp_gscr_rev(gscr), |
318 | nr_ports, gscr[SATA_PMP_GSCR_FEAT_EN], |
319 | gscr[SATA_PMP_GSCR_FEAT]); |
320 | |
321 | if (!(dev->flags & ATA_DFLAG_AN)) |
322 | ata_dev_info(dev, |
323 | "Asynchronous notification not supported, " |
324 | "hotplug won't work on fan-out ports. Use warm-plug instead.\n" ); |
325 | } |
326 | |
327 | return 0; |
328 | |
329 | fail: |
330 | ata_dev_err(dev, |
331 | "failed to configure Port Multiplier (%s, Emask=0x%x)\n" , |
332 | reason, err_mask); |
333 | return rc; |
334 | } |
335 | |
336 | static int sata_pmp_init_links (struct ata_port *ap, int nr_ports) |
337 | { |
338 | struct ata_link *pmp_link = ap->pmp_link; |
339 | int i, err; |
340 | |
341 | if (!pmp_link) { |
342 | pmp_link = kcalloc(n: SATA_PMP_MAX_PORTS, size: sizeof(pmp_link[0]), |
343 | GFP_NOIO); |
344 | if (!pmp_link) |
345 | return -ENOMEM; |
346 | |
347 | for (i = 0; i < SATA_PMP_MAX_PORTS; i++) |
348 | ata_link_init(ap, link: &pmp_link[i], pmp: i); |
349 | |
350 | ap->pmp_link = pmp_link; |
351 | |
352 | for (i = 0; i < SATA_PMP_MAX_PORTS; i++) { |
353 | err = ata_tlink_add(link: &pmp_link[i]); |
354 | if (err) { |
355 | goto err_tlink; |
356 | } |
357 | } |
358 | } |
359 | |
360 | for (i = 0; i < nr_ports; i++) { |
361 | struct ata_link *link = &pmp_link[i]; |
362 | struct ata_eh_context *ehc = &link->eh_context; |
363 | |
364 | link->flags = 0; |
365 | ehc->i.probe_mask |= ATA_ALL_DEVICES; |
366 | ehc->i.action |= ATA_EH_RESET; |
367 | } |
368 | |
369 | return 0; |
370 | err_tlink: |
371 | while (--i >= 0) |
372 | ata_tlink_delete(link: &pmp_link[i]); |
373 | kfree(objp: pmp_link); |
374 | ap->pmp_link = NULL; |
375 | return err; |
376 | } |
377 | |
378 | static void sata_pmp_quirks(struct ata_port *ap) |
379 | { |
380 | u32 *gscr = ap->link.device->gscr; |
381 | u16 vendor = sata_pmp_gscr_vendor(gscr); |
382 | u16 devid = sata_pmp_gscr_devid(gscr); |
383 | struct ata_link *link; |
384 | |
385 | if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) { |
386 | /* sil3x26 quirks */ |
387 | ata_for_each_link(link, ap, EDGE) { |
388 | /* link reports offline after LPM */ |
389 | link->flags |= ATA_LFLAG_NO_LPM; |
390 | |
391 | /* |
392 | * Class code report is unreliable and SRST times |
393 | * out under certain configurations. |
394 | */ |
395 | if (link->pmp < 5) |
396 | link->flags |= ATA_LFLAG_NO_SRST | |
397 | ATA_LFLAG_ASSUME_ATA; |
398 | |
399 | /* port 5 is for SEMB device and it doesn't like SRST */ |
400 | if (link->pmp == 5) |
401 | link->flags |= ATA_LFLAG_NO_SRST | |
402 | ATA_LFLAG_ASSUME_SEMB; |
403 | } |
404 | } else if (vendor == 0x1095 && devid == 0x4723) { |
405 | /* |
406 | * sil4723 quirks |
407 | * |
408 | * Link reports offline after LPM. Class code report is |
409 | * unreliable. SIMG PMPs never got SRST reliable and the |
410 | * config device at port 2 locks up on SRST. |
411 | */ |
412 | ata_for_each_link(link, ap, EDGE) |
413 | link->flags |= ATA_LFLAG_NO_LPM | |
414 | ATA_LFLAG_NO_SRST | |
415 | ATA_LFLAG_ASSUME_ATA; |
416 | } else if (vendor == 0x1095 && devid == 0x4726) { |
417 | /* sil4726 quirks */ |
418 | ata_for_each_link(link, ap, EDGE) { |
419 | /* link reports offline after LPM */ |
420 | link->flags |= ATA_LFLAG_NO_LPM; |
421 | |
422 | /* Class code report is unreliable and SRST |
423 | * times out under certain configurations. |
424 | * Config device can be at port 0 or 5 and |
425 | * locks up on SRST. |
426 | */ |
427 | if (link->pmp <= 5) |
428 | link->flags |= ATA_LFLAG_NO_SRST | |
429 | ATA_LFLAG_ASSUME_ATA; |
430 | |
431 | /* Port 6 is for SEMB device which doesn't |
432 | * like SRST either. |
433 | */ |
434 | if (link->pmp == 6) |
435 | link->flags |= ATA_LFLAG_NO_SRST | |
436 | ATA_LFLAG_ASSUME_SEMB; |
437 | } |
438 | } else if (vendor == 0x1095 && (devid == 0x5723 || devid == 0x5733 || |
439 | devid == 0x5734 || devid == 0x5744)) { |
440 | /* sil5723/5744 quirks */ |
441 | |
442 | /* sil5723/5744 has either two or three downstream |
443 | * ports depending on operation mode. The last port |
444 | * is empty if any actual IO device is available or |
445 | * occupied by a pseudo configuration device |
446 | * otherwise. Don't try hard to recover it. |
447 | */ |
448 | ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY; |
449 | } else if (vendor == 0x197b && (devid == 0x2352 || devid == 0x0325)) { |
450 | /* |
451 | * 0x2352: found in Thermaltake BlackX Duet, jmicron JMB350? |
452 | * 0x0325: jmicron JMB394. |
453 | */ |
454 | ata_for_each_link(link, ap, EDGE) { |
455 | /* SRST breaks detection and disks get misclassified |
456 | * LPM disabled to avoid potential problems |
457 | */ |
458 | link->flags |= ATA_LFLAG_NO_LPM | |
459 | ATA_LFLAG_NO_SRST | |
460 | ATA_LFLAG_ASSUME_ATA; |
461 | } |
462 | } else if (vendor == 0x11ab && devid == 0x4140) { |
463 | /* Marvell 4140 quirks */ |
464 | ata_for_each_link(link, ap, EDGE) { |
465 | /* port 4 is for SEMB device and it doesn't like SRST */ |
466 | if (link->pmp == 4) |
467 | link->flags |= ATA_LFLAG_DISABLED; |
468 | } |
469 | } |
470 | } |
471 | |
472 | /** |
473 | * sata_pmp_attach - attach a SATA PMP device |
474 | * @dev: SATA PMP device to attach |
475 | * |
476 | * Configure and attach SATA PMP device @dev. This function is |
477 | * also responsible for allocating and initializing PMP links. |
478 | * |
479 | * LOCKING: |
480 | * Kernel thread context (may sleep). |
481 | * |
482 | * RETURNS: |
483 | * 0 on success, -errno on failure. |
484 | */ |
485 | int sata_pmp_attach(struct ata_device *dev) |
486 | { |
487 | struct ata_link *link = dev->link; |
488 | struct ata_port *ap = link->ap; |
489 | unsigned long flags; |
490 | struct ata_link *tlink; |
491 | int rc; |
492 | |
493 | /* is it hanging off the right place? */ |
494 | if (!sata_pmp_supported(ap)) { |
495 | ata_dev_err(dev, "host does not support Port Multiplier\n" ); |
496 | return -EINVAL; |
497 | } |
498 | |
499 | if (!ata_is_host_link(link)) { |
500 | ata_dev_err(dev, "Port Multipliers cannot be nested\n" ); |
501 | return -EINVAL; |
502 | } |
503 | |
504 | if (dev->devno) { |
505 | ata_dev_err(dev, "Port Multiplier must be the first device\n" ); |
506 | return -EINVAL; |
507 | } |
508 | |
509 | WARN_ON(link->pmp != 0); |
510 | link->pmp = SATA_PMP_CTRL_PORT; |
511 | |
512 | /* read GSCR block */ |
513 | rc = sata_pmp_read_gscr(dev, gscr: dev->gscr); |
514 | if (rc) |
515 | goto fail; |
516 | |
517 | /* config PMP */ |
518 | rc = sata_pmp_configure(dev, print_info: 1); |
519 | if (rc) |
520 | goto fail; |
521 | |
522 | rc = sata_pmp_init_links(ap, sata_pmp_gscr_ports(dev->gscr)); |
523 | if (rc) { |
524 | ata_dev_info(dev, "failed to initialize PMP links\n" ); |
525 | goto fail; |
526 | } |
527 | |
528 | /* attach it */ |
529 | spin_lock_irqsave(ap->lock, flags); |
530 | WARN_ON(ap->nr_pmp_links); |
531 | ap->nr_pmp_links = sata_pmp_gscr_ports(dev->gscr); |
532 | spin_unlock_irqrestore(lock: ap->lock, flags); |
533 | |
534 | sata_pmp_quirks(ap); |
535 | |
536 | if (ap->ops->pmp_attach) |
537 | ap->ops->pmp_attach(ap); |
538 | |
539 | ata_for_each_link(tlink, ap, EDGE) |
540 | sata_link_init_spd(link: tlink); |
541 | |
542 | return 0; |
543 | |
544 | fail: |
545 | link->pmp = 0; |
546 | return rc; |
547 | } |
548 | |
549 | /** |
550 | * sata_pmp_detach - detach a SATA PMP device |
551 | * @dev: SATA PMP device to detach |
552 | * |
553 | * Detach SATA PMP device @dev. This function is also |
554 | * responsible for deconfiguring PMP links. |
555 | * |
556 | * LOCKING: |
557 | * Kernel thread context (may sleep). |
558 | */ |
559 | static void sata_pmp_detach(struct ata_device *dev) |
560 | { |
561 | struct ata_link *link = dev->link; |
562 | struct ata_port *ap = link->ap; |
563 | struct ata_link *tlink; |
564 | unsigned long flags; |
565 | |
566 | ata_dev_info(dev, "Port Multiplier detaching\n" ); |
567 | |
568 | WARN_ON(!ata_is_host_link(link) || dev->devno || |
569 | link->pmp != SATA_PMP_CTRL_PORT); |
570 | |
571 | if (ap->ops->pmp_detach) |
572 | ap->ops->pmp_detach(ap); |
573 | |
574 | ata_for_each_link(tlink, ap, EDGE) |
575 | ata_eh_detach_dev(dev: tlink->device); |
576 | |
577 | spin_lock_irqsave(ap->lock, flags); |
578 | ap->nr_pmp_links = 0; |
579 | link->pmp = 0; |
580 | spin_unlock_irqrestore(lock: ap->lock, flags); |
581 | } |
582 | |
583 | /** |
584 | * sata_pmp_same_pmp - does new GSCR matches the configured PMP? |
585 | * @dev: PMP device to compare against |
586 | * @new_gscr: GSCR block of the new device |
587 | * |
588 | * Compare @new_gscr against @dev and determine whether @dev is |
589 | * the PMP described by @new_gscr. |
590 | * |
591 | * LOCKING: |
592 | * None. |
593 | * |
594 | * RETURNS: |
595 | * 1 if @dev matches @new_gscr, 0 otherwise. |
596 | */ |
597 | static int sata_pmp_same_pmp(struct ata_device *dev, const u32 *new_gscr) |
598 | { |
599 | const u32 *old_gscr = dev->gscr; |
600 | u16 old_vendor, new_vendor, old_devid, new_devid; |
601 | int old_nr_ports, new_nr_ports; |
602 | |
603 | old_vendor = sata_pmp_gscr_vendor(old_gscr); |
604 | new_vendor = sata_pmp_gscr_vendor(new_gscr); |
605 | old_devid = sata_pmp_gscr_devid(old_gscr); |
606 | new_devid = sata_pmp_gscr_devid(new_gscr); |
607 | old_nr_ports = sata_pmp_gscr_ports(old_gscr); |
608 | new_nr_ports = sata_pmp_gscr_ports(new_gscr); |
609 | |
610 | if (old_vendor != new_vendor) { |
611 | ata_dev_info(dev, |
612 | "Port Multiplier vendor mismatch '0x%x' != '0x%x'\n" , |
613 | old_vendor, new_vendor); |
614 | return 0; |
615 | } |
616 | |
617 | if (old_devid != new_devid) { |
618 | ata_dev_info(dev, |
619 | "Port Multiplier device ID mismatch '0x%x' != '0x%x'\n" , |
620 | old_devid, new_devid); |
621 | return 0; |
622 | } |
623 | |
624 | if (old_nr_ports != new_nr_ports) { |
625 | ata_dev_info(dev, |
626 | "Port Multiplier nr_ports mismatch '0x%x' != '0x%x'\n" , |
627 | old_nr_ports, new_nr_ports); |
628 | return 0; |
629 | } |
630 | |
631 | return 1; |
632 | } |
633 | |
634 | /** |
635 | * sata_pmp_revalidate - revalidate SATA PMP |
636 | * @dev: PMP device to revalidate |
637 | * @new_class: new class code |
638 | * |
639 | * Re-read GSCR block and make sure @dev is still attached to the |
640 | * port and properly configured. |
641 | * |
642 | * LOCKING: |
643 | * Kernel thread context (may sleep). |
644 | * |
645 | * RETURNS: |
646 | * 0 on success, -errno otherwise. |
647 | */ |
648 | static int sata_pmp_revalidate(struct ata_device *dev, unsigned int new_class) |
649 | { |
650 | struct ata_link *link = dev->link; |
651 | struct ata_port *ap = link->ap; |
652 | u32 *gscr = (void *)ap->sector_buf; |
653 | int rc; |
654 | |
655 | ata_eh_about_to_do(link, NULL, action: ATA_EH_REVALIDATE); |
656 | |
657 | if (!ata_dev_enabled(dev)) { |
658 | rc = -ENODEV; |
659 | goto fail; |
660 | } |
661 | |
662 | /* wrong class? */ |
663 | if (ata_class_enabled(class: new_class) && new_class != ATA_DEV_PMP) { |
664 | rc = -ENODEV; |
665 | goto fail; |
666 | } |
667 | |
668 | /* read GSCR */ |
669 | rc = sata_pmp_read_gscr(dev, gscr); |
670 | if (rc) |
671 | goto fail; |
672 | |
673 | /* is the pmp still there? */ |
674 | if (!sata_pmp_same_pmp(dev, new_gscr: gscr)) { |
675 | rc = -ENODEV; |
676 | goto fail; |
677 | } |
678 | |
679 | memcpy(dev->gscr, gscr, sizeof(gscr[0]) * SATA_PMP_GSCR_DWORDS); |
680 | |
681 | rc = sata_pmp_configure(dev, print_info: 0); |
682 | if (rc) |
683 | goto fail; |
684 | |
685 | ata_eh_done(link, NULL, action: ATA_EH_REVALIDATE); |
686 | |
687 | return 0; |
688 | |
689 | fail: |
690 | ata_dev_err(dev, "PMP revalidation failed (errno=%d)\n" , rc); |
691 | return rc; |
692 | } |
693 | |
694 | /** |
695 | * sata_pmp_revalidate_quick - revalidate SATA PMP quickly |
696 | * @dev: PMP device to revalidate |
697 | * |
698 | * Make sure the attached PMP is accessible. |
699 | * |
700 | * LOCKING: |
701 | * Kernel thread context (may sleep). |
702 | * |
703 | * RETURNS: |
704 | * 0 on success, -errno otherwise. |
705 | */ |
706 | static int sata_pmp_revalidate_quick(struct ata_device *dev) |
707 | { |
708 | unsigned int err_mask; |
709 | u32 prod_id; |
710 | |
711 | err_mask = sata_pmp_read(link: dev->link, reg: SATA_PMP_GSCR_PROD_ID, r_val: &prod_id); |
712 | if (err_mask) { |
713 | ata_dev_err(dev, |
714 | "failed to read PMP product ID (Emask=0x%x)\n" , |
715 | err_mask); |
716 | return -EIO; |
717 | } |
718 | |
719 | if (prod_id != dev->gscr[SATA_PMP_GSCR_PROD_ID]) { |
720 | ata_dev_err(dev, "PMP product ID mismatch\n" ); |
721 | /* something weird is going on, request full PMP recovery */ |
722 | return -EIO; |
723 | } |
724 | |
725 | return 0; |
726 | } |
727 | |
728 | /** |
729 | * sata_pmp_eh_recover_pmp - recover PMP |
730 | * @ap: ATA port PMP is attached to |
731 | * @prereset: prereset method (can be NULL) |
732 | * @softreset: softreset method |
733 | * @hardreset: hardreset method |
734 | * @postreset: postreset method (can be NULL) |
735 | * |
736 | * Recover PMP attached to @ap. Recovery procedure is somewhat |
737 | * similar to that of ata_eh_recover() except that reset should |
738 | * always be performed in hard->soft sequence and recovery |
739 | * failure results in PMP detachment. |
740 | * |
741 | * LOCKING: |
742 | * Kernel thread context (may sleep). |
743 | * |
744 | * RETURNS: |
745 | * 0 on success, -errno on failure. |
746 | */ |
747 | static int sata_pmp_eh_recover_pmp(struct ata_port *ap, |
748 | ata_prereset_fn_t prereset, ata_reset_fn_t softreset, |
749 | ata_reset_fn_t hardreset, ata_postreset_fn_t postreset) |
750 | { |
751 | struct ata_link *link = &ap->link; |
752 | struct ata_eh_context *ehc = &link->eh_context; |
753 | struct ata_device *dev = link->device; |
754 | int tries = ATA_EH_PMP_TRIES; |
755 | int detach = 0, rc = 0; |
756 | int reval_failed = 0; |
757 | |
758 | if (dev->flags & ATA_DFLAG_DETACH) { |
759 | detach = 1; |
760 | rc = -ENODEV; |
761 | goto fail; |
762 | } |
763 | |
764 | retry: |
765 | ehc->classes[0] = ATA_DEV_UNKNOWN; |
766 | |
767 | if (ehc->i.action & ATA_EH_RESET) { |
768 | struct ata_link *tlink; |
769 | |
770 | /* reset */ |
771 | rc = ata_eh_reset(link, classify: 0, prereset, softreset, hardreset, |
772 | postreset); |
773 | if (rc) { |
774 | ata_link_err(link, "failed to reset PMP, giving up\n" ); |
775 | goto fail; |
776 | } |
777 | |
778 | /* PMP is reset, SErrors cannot be trusted, scan all */ |
779 | ata_for_each_link(tlink, ap, EDGE) { |
780 | struct ata_eh_context *ehc = &tlink->eh_context; |
781 | |
782 | ehc->i.probe_mask |= ATA_ALL_DEVICES; |
783 | ehc->i.action |= ATA_EH_RESET; |
784 | } |
785 | } |
786 | |
787 | /* If revalidation is requested, revalidate and reconfigure; |
788 | * otherwise, do quick revalidation. |
789 | */ |
790 | if (ehc->i.action & ATA_EH_REVALIDATE) |
791 | rc = sata_pmp_revalidate(dev, new_class: ehc->classes[0]); |
792 | else |
793 | rc = sata_pmp_revalidate_quick(dev); |
794 | |
795 | if (rc) { |
796 | tries--; |
797 | |
798 | if (rc == -ENODEV) { |
799 | ehc->i.probe_mask |= ATA_ALL_DEVICES; |
800 | detach = 1; |
801 | /* give it just two more chances */ |
802 | tries = min(tries, 2); |
803 | } |
804 | |
805 | if (tries) { |
806 | /* consecutive revalidation failures? speed down */ |
807 | if (reval_failed) |
808 | sata_down_spd_limit(link, spd_limit: 0); |
809 | else |
810 | reval_failed = 1; |
811 | |
812 | ehc->i.action |= ATA_EH_RESET; |
813 | goto retry; |
814 | } else { |
815 | ata_dev_err(dev, |
816 | "failed to recover PMP after %d tries, giving up\n" , |
817 | ATA_EH_PMP_TRIES); |
818 | goto fail; |
819 | } |
820 | } |
821 | |
822 | /* okay, PMP resurrected */ |
823 | ehc->i.flags = 0; |
824 | |
825 | return 0; |
826 | |
827 | fail: |
828 | sata_pmp_detach(dev); |
829 | if (detach) |
830 | ata_eh_detach_dev(dev); |
831 | else |
832 | ata_dev_disable(dev); |
833 | |
834 | return rc; |
835 | } |
836 | |
837 | static int sata_pmp_eh_handle_disabled_links(struct ata_port *ap) |
838 | { |
839 | struct ata_link *link; |
840 | unsigned long flags; |
841 | int rc; |
842 | |
843 | spin_lock_irqsave(ap->lock, flags); |
844 | |
845 | ata_for_each_link(link, ap, EDGE) { |
846 | if (!(link->flags & ATA_LFLAG_DISABLED)) |
847 | continue; |
848 | |
849 | spin_unlock_irqrestore(lock: ap->lock, flags); |
850 | |
851 | /* Some PMPs require hardreset sequence to get |
852 | * SError.N working. |
853 | */ |
854 | sata_link_hardreset(link, timing: sata_deb_timing_normal, |
855 | deadline: ata_deadline(from_jiffies: jiffies, timeout_msecs: ATA_TMOUT_INTERNAL_QUICK), |
856 | NULL, NULL); |
857 | |
858 | /* unconditionally clear SError.N */ |
859 | rc = sata_scr_write(link, reg: SCR_ERROR, val: SERR_PHYRDY_CHG); |
860 | if (rc) { |
861 | ata_link_err(link, |
862 | "failed to clear SError.N (errno=%d)\n" , |
863 | rc); |
864 | return rc; |
865 | } |
866 | |
867 | spin_lock_irqsave(ap->lock, flags); |
868 | } |
869 | |
870 | spin_unlock_irqrestore(lock: ap->lock, flags); |
871 | |
872 | return 0; |
873 | } |
874 | |
875 | static int sata_pmp_handle_link_fail(struct ata_link *link, int *link_tries) |
876 | { |
877 | struct ata_port *ap = link->ap; |
878 | unsigned long flags; |
879 | |
880 | if (link_tries[link->pmp] && --link_tries[link->pmp]) |
881 | return 1; |
882 | |
883 | /* disable this link */ |
884 | if (!(link->flags & ATA_LFLAG_DISABLED)) { |
885 | ata_link_warn(link, |
886 | "failed to recover link after %d tries, disabling\n" , |
887 | ATA_EH_PMP_LINK_TRIES); |
888 | |
889 | spin_lock_irqsave(ap->lock, flags); |
890 | link->flags |= ATA_LFLAG_DISABLED; |
891 | spin_unlock_irqrestore(lock: ap->lock, flags); |
892 | } |
893 | |
894 | ata_dev_disable(dev: link->device); |
895 | link->eh_context.i.action = 0; |
896 | |
897 | return 0; |
898 | } |
899 | |
900 | /** |
901 | * sata_pmp_eh_recover - recover PMP-enabled port |
902 | * @ap: ATA port to recover |
903 | * |
904 | * Drive EH recovery operation for PMP enabled port @ap. This |
905 | * function recovers host and PMP ports with proper retrials and |
906 | * fallbacks. Actual recovery operations are performed using |
907 | * ata_eh_recover() and sata_pmp_eh_recover_pmp(). |
908 | * |
909 | * LOCKING: |
910 | * Kernel thread context (may sleep). |
911 | * |
912 | * RETURNS: |
913 | * 0 on success, -errno on failure. |
914 | */ |
915 | static int sata_pmp_eh_recover(struct ata_port *ap) |
916 | { |
917 | struct ata_port_operations *ops = ap->ops; |
918 | int pmp_tries, link_tries[SATA_PMP_MAX_PORTS]; |
919 | struct ata_link *pmp_link = &ap->link; |
920 | struct ata_device *pmp_dev = pmp_link->device; |
921 | struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; |
922 | u32 *gscr = pmp_dev->gscr; |
923 | struct ata_link *link; |
924 | struct ata_device *dev; |
925 | unsigned int err_mask; |
926 | u32 gscr_error, sntf; |
927 | int cnt, rc; |
928 | |
929 | pmp_tries = ATA_EH_PMP_TRIES; |
930 | ata_for_each_link(link, ap, EDGE) |
931 | link_tries[link->pmp] = ATA_EH_PMP_LINK_TRIES; |
932 | |
933 | retry: |
934 | /* PMP attached? */ |
935 | if (!sata_pmp_attached(ap)) { |
936 | rc = ata_eh_recover(ap, prereset: ops->prereset, softreset: ops->softreset, |
937 | hardreset: ops->hardreset, postreset: ops->postreset, NULL); |
938 | if (rc) { |
939 | ata_for_each_dev(dev, &ap->link, ALL) |
940 | ata_dev_disable(dev); |
941 | return rc; |
942 | } |
943 | |
944 | if (pmp_dev->class != ATA_DEV_PMP) |
945 | return 0; |
946 | |
947 | /* new PMP online */ |
948 | ata_for_each_link(link, ap, EDGE) |
949 | link_tries[link->pmp] = ATA_EH_PMP_LINK_TRIES; |
950 | |
951 | /* fall through */ |
952 | } |
953 | |
954 | /* recover pmp */ |
955 | rc = sata_pmp_eh_recover_pmp(ap, prereset: ops->prereset, softreset: ops->softreset, |
956 | hardreset: ops->hardreset, postreset: ops->postreset); |
957 | if (rc) |
958 | goto pmp_fail; |
959 | |
960 | /* PHY event notification can disturb reset and other recovery |
961 | * operations. Turn it off. |
962 | */ |
963 | if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) { |
964 | gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY; |
965 | |
966 | err_mask = sata_pmp_write(link: pmp_link, reg: SATA_PMP_GSCR_FEAT_EN, |
967 | val: gscr[SATA_PMP_GSCR_FEAT_EN]); |
968 | if (err_mask) { |
969 | ata_link_warn(pmp_link, |
970 | "failed to disable NOTIFY (err_mask=0x%x)\n" , |
971 | err_mask); |
972 | goto pmp_fail; |
973 | } |
974 | } |
975 | |
976 | /* handle disabled links */ |
977 | rc = sata_pmp_eh_handle_disabled_links(ap); |
978 | if (rc) |
979 | goto pmp_fail; |
980 | |
981 | /* recover links */ |
982 | rc = ata_eh_recover(ap, prereset: ops->pmp_prereset, softreset: ops->pmp_softreset, |
983 | hardreset: ops->pmp_hardreset, postreset: ops->pmp_postreset, r_failed_disk: &link); |
984 | if (rc) |
985 | goto link_fail; |
986 | |
987 | /* clear SNotification */ |
988 | rc = sata_scr_read(link: &ap->link, reg: SCR_NOTIFICATION, val: &sntf); |
989 | if (rc == 0) |
990 | sata_scr_write(link: &ap->link, reg: SCR_NOTIFICATION, val: sntf); |
991 | |
992 | /* |
993 | * If LPM is active on any fan-out port, hotplug wouldn't |
994 | * work. Return w/ PHY event notification disabled. |
995 | */ |
996 | ata_for_each_link(link, ap, EDGE) |
997 | if (link->lpm_policy > ATA_LPM_MAX_POWER) |
998 | return 0; |
999 | |
1000 | /* |
1001 | * Connection status might have changed while resetting other |
1002 | * links, enable notification and check SATA_PMP_GSCR_ERROR |
1003 | * before returning. |
1004 | */ |
1005 | |
1006 | /* enable notification */ |
1007 | if (pmp_dev->flags & ATA_DFLAG_AN) { |
1008 | gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; |
1009 | |
1010 | err_mask = sata_pmp_write(link: pmp_link, reg: SATA_PMP_GSCR_FEAT_EN, |
1011 | val: gscr[SATA_PMP_GSCR_FEAT_EN]); |
1012 | if (err_mask) { |
1013 | ata_dev_err(pmp_dev, |
1014 | "failed to write PMP_FEAT_EN (Emask=0x%x)\n" , |
1015 | err_mask); |
1016 | rc = -EIO; |
1017 | goto pmp_fail; |
1018 | } |
1019 | } |
1020 | |
1021 | /* check GSCR_ERROR */ |
1022 | err_mask = sata_pmp_read(link: pmp_link, reg: SATA_PMP_GSCR_ERROR, r_val: &gscr_error); |
1023 | if (err_mask) { |
1024 | ata_dev_err(pmp_dev, |
1025 | "failed to read PMP_GSCR_ERROR (Emask=0x%x)\n" , |
1026 | err_mask); |
1027 | rc = -EIO; |
1028 | goto pmp_fail; |
1029 | } |
1030 | |
1031 | cnt = 0; |
1032 | ata_for_each_link(link, ap, EDGE) { |
1033 | if (!(gscr_error & (1 << link->pmp))) |
1034 | continue; |
1035 | |
1036 | if (sata_pmp_handle_link_fail(link, link_tries)) { |
1037 | ata_ehi_hotplugged(ehi: &link->eh_context.i); |
1038 | cnt++; |
1039 | } else { |
1040 | ata_link_warn(link, |
1041 | "PHY status changed but maxed out on retries, giving up\n" ); |
1042 | ata_link_warn(link, |
1043 | "Manually issue scan to resume this link\n" ); |
1044 | } |
1045 | } |
1046 | |
1047 | if (cnt) { |
1048 | ata_port_info(ap, |
1049 | "PMP SError.N set for some ports, repeating recovery\n" ); |
1050 | goto retry; |
1051 | } |
1052 | |
1053 | return 0; |
1054 | |
1055 | link_fail: |
1056 | if (sata_pmp_handle_link_fail(link, link_tries)) { |
1057 | pmp_ehc->i.action |= ATA_EH_RESET; |
1058 | goto retry; |
1059 | } |
1060 | |
1061 | /* fall through */ |
1062 | pmp_fail: |
1063 | /* Control always ends up here after detaching PMP. Shut up |
1064 | * and return if we're unloading. |
1065 | */ |
1066 | if (ap->pflags & ATA_PFLAG_UNLOADING) |
1067 | return rc; |
1068 | |
1069 | if (!sata_pmp_attached(ap)) |
1070 | goto retry; |
1071 | |
1072 | if (--pmp_tries) { |
1073 | pmp_ehc->i.action |= ATA_EH_RESET; |
1074 | goto retry; |
1075 | } |
1076 | |
1077 | ata_port_err(ap, "failed to recover PMP after %d tries, giving up\n" , |
1078 | ATA_EH_PMP_TRIES); |
1079 | sata_pmp_detach(dev: pmp_dev); |
1080 | ata_dev_disable(dev: pmp_dev); |
1081 | |
1082 | return rc; |
1083 | } |
1084 | |
1085 | /** |
1086 | * sata_pmp_error_handler - do standard error handling for PMP-enabled host |
1087 | * @ap: host port to handle error for |
1088 | * |
1089 | * Perform standard error handling sequence for PMP-enabled host |
1090 | * @ap. |
1091 | * |
1092 | * LOCKING: |
1093 | * Kernel thread context (may sleep). |
1094 | */ |
1095 | void sata_pmp_error_handler(struct ata_port *ap) |
1096 | { |
1097 | ata_eh_autopsy(ap); |
1098 | ata_eh_report(ap); |
1099 | sata_pmp_eh_recover(ap); |
1100 | ata_eh_finish(ap); |
1101 | } |
1102 | |
1103 | EXPORT_SYMBOL_GPL(sata_pmp_port_ops); |
1104 | EXPORT_SYMBOL_GPL(sata_pmp_qc_defer_cmd_switch); |
1105 | EXPORT_SYMBOL_GPL(sata_pmp_error_handler); |
1106 | |