1 /* $OpenBSD: sili.c,v 1.62 2024/09/04 07:54:52 mglocker Exp $ */
2
3 /*
4 * Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
5 * Copyright (c) 2010 Conformal Systems LLC <info@conformal.com>
6 * Copyright (c) 2010 Jonathan Matthew <jonathan@d14n.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21 #include <sys/param.h>
22 #include <sys/systm.h>
23 #include <sys/device.h>
24 #include <sys/timeout.h>
25 #include <sys/malloc.h>
26 #include <sys/kernel.h>
27 #include <sys/mutex.h>
28
29 #include <machine/bus.h>
30
31 #include <dev/ata/atascsi.h>
32 #include <dev/ata/pmreg.h>
33
34 #include <dev/ic/silireg.h>
35 #include <dev/ic/silivar.h>
36
37 /* use SILI_DEBUG for dmesg spam */
38 #define NO_SILI_DEBUG
39
40 #ifdef SILI_DEBUG
41 #define SILI_D_VERBOSE (1<<0)
42 #define SILI_D_INTR (1<<1)
43
44 int silidebug = SILI_D_VERBOSE;
45
46 #define DPRINTF(m, a...) do { if ((m) & silidebug) printf(a); } while (0)
47 #else
48 #define DPRINTF(m, a...)
49 #endif
50
51 /* these can be used to simulate read and write errors on specific PMP ports */
52 #undef SILI_ERROR_TEST
53 int sili_error_pmp_ports = 0; /* bitmask containing ports to fail*/
54 int sili_error_test_inv_p = 500; /* 1/P(error) */
55 int sili_error_restart_type = SILI_PREG_PCS_PORTINIT; /* or _DEVRESET */
56
57 struct cfdriver sili_cd = {
58 NULL, "sili", DV_DULL
59 };
60
61 /* wrapper around dma memory */
62 struct sili_dmamem {
63 bus_dmamap_t sdm_map;
64 bus_dma_segment_t sdm_seg;
65 size_t sdm_size;
66 caddr_t sdm_kva;
67 };
68 #define SILI_DMA_MAP(_sdm) ((_sdm)->sdm_map)
69 #define SILI_DMA_DVA(_sdm) ((_sdm)->sdm_map->dm_segs[0].ds_addr)
70 #define SILI_DMA_KVA(_sdm) ((_sdm)->sdm_kva)
71
72 struct sili_dmamem *sili_dmamem_alloc(struct sili_softc *, bus_size_t,
73 bus_size_t);
74 void sili_dmamem_free(struct sili_softc *,
75 struct sili_dmamem *);
76
77 /* per port goo */
78 struct sili_ccb;
79
80 /* size of scratch space for use in error recovery. */
81 #define SILI_SCRATCH_LEN 512 /* must be at least 1 sector */
82
83 struct sili_port {
84 struct sili_softc *sp_sc;
85 bus_space_handle_t sp_ioh;
86
87 struct sili_ccb *sp_ccbs;
88 struct sili_dmamem *sp_cmds;
89 struct sili_dmamem *sp_scratch;
90
91 TAILQ_HEAD(, sili_ccb) sp_free_ccbs;
92 struct mutex sp_free_ccb_mtx;
93
94 volatile u_int32_t sp_active;
95 TAILQ_HEAD(, sili_ccb) sp_active_ccbs;
96 TAILQ_HEAD(, sili_ccb) sp_deferred_ccbs;
97
98 int sp_port;
99 int sp_pmp_ports;
100 int sp_active_pmp_ports;
101 int sp_pmp_error_recovery; /* port bitmask */
102 volatile u_int32_t sp_err_active; /* cmd bitmask */
103 volatile u_int32_t sp_err_cmds; /* cmd bitmask */
104
105 #ifdef SILI_DEBUG
106 char sp_name[16];
107 #define PORTNAME(_sp) ((_sp)->sp_name)
108 #else
109 #define PORTNAME(_sp) DEVNAME((_sp)->sp_sc)
110 #endif
111 };
112
113 int sili_ports_alloc(struct sili_softc *);
114 void sili_ports_free(struct sili_softc *);
115
116 /* ccb shizz */
117
118 /*
119 * the dma memory for each command will be made up of a prb followed by
120 * 7 sgts, this is a neat 512 bytes.
121 */
122 #define SILI_CMD_LEN 512
123
124 /*
125 * you can fit 22 sge's into 7 sgts and a prb:
126 * there's 1 sgl in an atapi prb (two in the ata one, but we can't over
127 * advertise), but that's needed for the chain element. you get three sges
128 * per sgt cos you lose the 4th sge for the chaining, but you keep it in
129 * the last sgt. so 3 x 6 + 4 is 22.
130 */
131 #define SILI_DMA_SEGS 22
132
133 struct sili_ccb {
134 struct ata_xfer ccb_xa;
135
136 void *ccb_cmd;
137 u_int64_t ccb_cmd_dva;
138 bus_dmamap_t ccb_dmamap;
139
140 struct sili_port *ccb_port;
141
142 TAILQ_ENTRY(sili_ccb) ccb_entry;
143 };
144
145 int sili_ccb_alloc(struct sili_port *);
146 void sili_ccb_free(struct sili_port *);
147 struct sili_ccb *sili_get_ccb(struct sili_port *);
148 void sili_put_ccb(struct sili_ccb *);
149
150 /* bus space ops */
151 u_int32_t sili_read(struct sili_softc *, bus_size_t);
152 void sili_write(struct sili_softc *, bus_size_t, u_int32_t);
153 u_int32_t sili_pread(struct sili_port *, bus_size_t);
154 void sili_pwrite(struct sili_port *, bus_size_t, u_int32_t);
155 int sili_pwait_eq(struct sili_port *, bus_size_t,
156 u_int32_t, u_int32_t, int);
157 int sili_pwait_ne(struct sili_port *, bus_size_t,
158 u_int32_t, u_int32_t, int);
159
160 /* command handling */
161 void sili_post_direct(struct sili_port *, u_int,
162 void *, size_t buflen);
163 void sili_post_indirect(struct sili_port *,
164 struct sili_ccb *);
165 void sili_pread_fis(struct sili_port *, u_int,
166 struct ata_fis_d2h *);
167 u_int32_t sili_signature(struct sili_port *, u_int);
168 u_int32_t sili_port_softreset(struct sili_port *sp);
169 int sili_load(struct sili_ccb *, struct sili_sge *, int);
170 void sili_unload(struct sili_ccb *);
171 int sili_poll(struct sili_ccb *, int, void (*)(void *));
172 void sili_start(struct sili_port *, struct sili_ccb *);
173 int sili_read_ncq_error(struct sili_port *, int *, int);
174 int sili_pmp_port_start_error_recovery(struct sili_port *,
175 int);
176 void sili_pmp_port_do_error_recovery(struct sili_port *,
177 int, u_int32_t *);
178 void sili_port_clear_commands(struct sili_port *sp);
179
180 /* pmp operations */
181 int sili_pmp_read(struct sili_port *, int, int,
182 u_int32_t *);
183 int sili_pmp_write(struct sili_port *, int, int, u_int32_t);
184 int sili_pmp_phy_status(struct sili_port *, int,
185 u_int32_t *);
186 int sili_pmp_identify(struct sili_port *, int *);
187
188 /* port interrupt handler */
189 u_int32_t sili_port_intr(struct sili_port *, int);
190
191 /* atascsi interface */
192 int sili_ata_probe(void *, int, int);
193 void sili_ata_free(void *, int, int);
194 struct ata_xfer *sili_ata_get_xfer(void *, int);
195 void sili_ata_put_xfer(struct ata_xfer *);
196 void sili_ata_cmd(struct ata_xfer *);
197 int sili_pmp_portreset(struct sili_softc *, int, int);
198 int sili_pmp_softreset(struct sili_softc *, int, int);
199
200 #ifdef SILI_ERROR_TEST
201 void sili_simulate_error(struct sili_ccb *ccb,
202 int *need_restart, int *err_port);
203 #endif
204
205 const struct atascsi_methods sili_atascsi_methods = {
206 sili_ata_probe,
207 sili_ata_free,
208 sili_ata_get_xfer,
209 sili_ata_put_xfer,
210 sili_ata_cmd
211 };
212
213 /* completion paths */
214 void sili_ata_cmd_done(struct sili_ccb *, int);
215 void sili_ata_cmd_timeout(void *);
216 void sili_dummy_done(struct ata_xfer *);
217
218 void sili_pmp_op_timeout(void *);
219
220 int
sili_attach(struct sili_softc * sc)221 sili_attach(struct sili_softc *sc)
222 {
223 struct atascsi_attach_args aaa;
224
225 printf("\n");
226
227 if (sili_ports_alloc(sc) != 0) {
228 /* error already printed by sili_port_alloc */
229 return (1);
230 }
231
232 /* bounce the controller */
233 sili_write(sc, SILI_REG_GC, SILI_REG_GC_GR);
234 sili_write(sc, SILI_REG_GC, 0x0);
235
236 bzero(&aaa, sizeof(aaa));
237 aaa.aaa_cookie = sc;
238 aaa.aaa_methods = &sili_atascsi_methods;
239 aaa.aaa_minphys = NULL;
240 aaa.aaa_nports = sc->sc_nports;
241 aaa.aaa_ncmds = SILI_MAX_CMDS;
242 aaa.aaa_capability = ASAA_CAP_NCQ | ASAA_CAP_PMP_NCQ;
243
244 sc->sc_atascsi = atascsi_attach(&sc->sc_dev, &aaa);
245
246 return (0);
247 }
248
249 int
sili_detach(struct sili_softc * sc,int flags)250 sili_detach(struct sili_softc *sc, int flags)
251 {
252 int rv;
253
254 if (sc->sc_atascsi != NULL) {
255 rv = atascsi_detach(sc->sc_atascsi, flags);
256 if (rv != 0)
257 return (rv);
258 }
259
260 if (sc->sc_ports != NULL)
261 sili_ports_free(sc);
262
263 return (0);
264 }
265
266 void
sili_resume(struct sili_softc * sc)267 sili_resume(struct sili_softc *sc)
268 {
269 int i, j;
270
271 /* bounce the controller */
272 sili_write(sc, SILI_REG_GC, SILI_REG_GC_GR);
273 sili_write(sc, SILI_REG_GC, 0x0);
274
275 for (i = 0; i < sc->sc_nports; i++) {
276 if (sili_ata_probe(sc, i, 0) == ATA_PORT_T_PM) {
277 struct sili_port *sp = &sc->sc_ports[i];
278 for (j = 0; j < sp->sp_pmp_ports; j++) {
279 sili_ata_probe(sc, i, j);
280 }
281 }
282 }
283 }
284
285 int
sili_pmp_port_start_error_recovery(struct sili_port * sp,int err_port)286 sili_pmp_port_start_error_recovery(struct sili_port *sp, int err_port)
287 {
288 struct sili_ccb *ccb;
289
290 sp->sp_pmp_error_recovery |= (1 << err_port);
291
292 /* create a bitmask of active commands on non-error ports */
293 sp->sp_err_active = 0;
294 TAILQ_FOREACH(ccb, &sp->sp_active_ccbs, ccb_entry) {
295 int bit = (1 << ccb->ccb_xa.pmp_port);
296 if ((sp->sp_pmp_error_recovery & bit) == 0) {
297 DPRINTF(SILI_D_VERBOSE, "%s: slot %d active on port "
298 "%d\n", PORTNAME(sp), ccb->ccb_xa.tag,
299 ccb->ccb_xa.pmp_port);
300 sp->sp_err_active |= (1 << ccb->ccb_xa.tag);
301 }
302 }
303
304 if (sp->sp_err_active == 0) {
305 DPRINTF(SILI_D_VERBOSE, "%s: no other PMP ports active\n",
306 PORTNAME(sp));
307 sp->sp_pmp_error_recovery = 0;
308 return (0);
309 }
310
311 /* set port resume */
312 sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_RESUME);
313
314 DPRINTF(SILI_D_VERBOSE, "%s: beginning error recovery (port %d); "
315 "error port mask %x, active slot mask %x\n", PORTNAME(sp), err_port,
316 sp->sp_pmp_error_recovery, sp->sp_err_active);
317 return (1);
318 }
319
320 void
sili_port_clear_commands(struct sili_port * sp)321 sili_port_clear_commands(struct sili_port *sp)
322 {
323 int port;
324
325 DPRINTF(SILI_D_VERBOSE, "%s: clearing active commands\n",
326 PORTNAME(sp));
327
328 /* clear port resume */
329 sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_RESUME);
330 delay(10000);
331
332 /* clear port status and port active for all ports */
333 for (port = 0; port < 16; port++) {
334 sili_pwrite(sp, SILI_PREG_PMP_STATUS(port), 0);
335 sili_pwrite(sp, SILI_PREG_PMP_QACTIVE(port), 0);
336 }
337 }
338
339 void
sili_pmp_port_do_error_recovery(struct sili_port * sp,int slot,u_int32_t * need_restart)340 sili_pmp_port_do_error_recovery(struct sili_port *sp, int slot,
341 u_int32_t *need_restart)
342 {
343 if (sp->sp_pmp_error_recovery == 0) {
344 return;
345 }
346
347 /* have all outstanding commands finished yet? */
348 if (sp->sp_err_active != 0) {
349 DPRINTF(SILI_D_VERBOSE, "%s: PMP error recovery still waiting "
350 "for %x\n", PORTNAME(sp), sp->sp_err_active);
351 *need_restart = 0;
352 return;
353 }
354
355 sili_port_clear_commands(sp);
356
357 /* get the main error recovery code to reset the port and
358 * resubmit commands. it will also reset the error recovery flags.
359 */
360 *need_restart = SILI_PREG_PCS_PORTINIT;
361 DPRINTF(SILI_D_VERBOSE, "%s: PMP error recovery complete\n",
362 PORTNAME(sp));
363 }
364
365 #ifdef SILI_ERROR_TEST
366 void
sili_simulate_error(struct sili_ccb * ccb,int * need_restart,int * err_port)367 sili_simulate_error(struct sili_ccb *ccb, int *need_restart, int *err_port)
368 {
369 struct sili_port *sp = ccb->ccb_port;
370
371 if (*need_restart == 0 &&
372 ((1 << ccb->ccb_xa.pmp_port) & sili_error_pmp_ports)) {
373 switch (ccb->ccb_xa.fis->command) {
374 case ATA_C_WRITE_FPDMA:
375 case ATA_C_READ_FPDMA:
376 case ATA_C_WRITEDMA_EXT:
377 case ATA_C_READDMA_EXT:
378 case ATA_C_WRITEDMA:
379 case ATA_C_READDMA:
380 if (arc4random_uniform(sili_error_test_inv_p) == 0) {
381 printf("%s: faking error on slot %d\n",
382 PORTNAME(sp), ccb->ccb_xa.tag);
383 ccb->ccb_xa.state = ATA_S_ERROR;
384 *need_restart = sili_error_restart_type;
385 *err_port = ccb->ccb_xa.pmp_port;
386
387 ccb->ccb_port->sp_err_cmds |=
388 (1 << ccb->ccb_xa.tag);
389 }
390 break;
391
392 default:
393 /* leave other commands alone, we only want to mess
394 * with normal read/write ops
395 */
396 break;
397 }
398 }
399 }
400 #endif
401
402 u_int32_t
sili_port_intr(struct sili_port * sp,int timeout_slot)403 sili_port_intr(struct sili_port *sp, int timeout_slot)
404 {
405 u_int32_t is, pss_saved, pss_masked;
406 u_int32_t processed = 0, need_restart = 0;
407 u_int32_t err_port = 0;
408 int slot;
409 struct sili_ccb *ccb;
410
411 is = sili_pread(sp, SILI_PREG_IS);
412 pss_saved = sili_pread(sp, SILI_PREG_PSS); /* reading acks CMDCOMP */
413
414 #ifdef SILI_DEBUG
415 if ((pss_saved & SILI_PREG_PSS_ALL_SLOTS) != sp->sp_active ||
416 ((is >> 16) & ~SILI_PREG_IS_CMDCOMP)) {
417 DPRINTF(SILI_D_INTR, "%s: IS: 0x%08x (0x%b), PSS: %08x, "
418 "active: %08x\n", PORTNAME(sp), is, is >> 16, SILI_PFMT_IS,
419 pss_saved, sp->sp_active);
420 }
421 #endif
422
423 /* Only interested in slot status bits. */
424 pss_saved &= SILI_PREG_PSS_ALL_SLOTS;
425
426 if (is & SILI_PREG_IS_CMDERR) {
427 int err_slot, err_code;
428 u_int32_t sactive = 0;
429
430 sili_pwrite(sp, SILI_PREG_IS, SILI_PREG_IS_CMDERR);
431 err_slot = SILI_PREG_PCS_ACTIVE(sili_pread(sp, SILI_PREG_PCS));
432 err_code = sili_pread(sp, SILI_PREG_CE);
433 ccb = &sp->sp_ccbs[err_slot];
434
435 switch (err_code) {
436 case SILI_PREG_CE_DEVICEERROR:
437 case SILI_PREG_CE_DATAFISERROR:
438 /* Extract error from command slot in LRAM. */
439 sili_pread_fis(sp, err_slot, &ccb->ccb_xa.rfis);
440 err_port = ccb->ccb_xa.pmp_port;
441 break;
442
443 case SILI_PREG_CE_SDBERROR:
444
445 if (sp->sp_pmp_ports > 0) {
446 /* get the PMP port number for the error */
447 err_port = (sili_pread(sp, SILI_PREG_CONTEXT)
448 >> SILI_PREG_CONTEXT_PMPORT_SHIFT) &
449 SILI_PREG_CONTEXT_PMPORT_MASK;
450 DPRINTF(SILI_D_VERBOSE, "%s: error port is "
451 "%d\n", PORTNAME(sp), err_port);
452
453 /* were there any NCQ commands active for
454 * the port?
455 */
456 sactive = sili_pread(sp,
457 SILI_PREG_PMP_QACTIVE(err_port));
458 DPRINTF(SILI_D_VERBOSE, "%s: error SActive "
459 "%x\n", PORTNAME(sp), sactive);
460 if (sactive == 0)
461 break;
462 } else {
463 /* No NCQ commands active? Treat as a normal
464 * error.
465 */
466 sactive = sili_pread(sp, SILI_PREG_SACT);
467 if (sactive == 0)
468 break;
469 }
470
471 /* Extract real NCQ error slot & RFIS from
472 * log page.
473 */
474 if (!sili_read_ncq_error(sp, &err_slot, err_port)) {
475 /* got real err_slot */
476 DPRINTF(SILI_D_VERBOSE, "%s.%d: error slot "
477 "%d\n", PORTNAME(sp), err_port, err_slot);
478 ccb = &sp->sp_ccbs[err_slot];
479 break;
480 }
481 DPRINTF(SILI_D_VERBOSE, "%s.%d: failed to get error "
482 "slot\n", PORTNAME(sp), err_port);
483
484 /* failed to get error or not NCQ */
485
486 /* FALLTHROUGH */
487 default:
488 /* All other error types are fatal. */
489 if (err_code != SILI_PREG_CE_SDBERROR) {
490 err_port = (sili_pread(sp, SILI_PREG_CONTEXT)
491 >> SILI_PREG_CONTEXT_PMPORT_SHIFT) &
492 SILI_PREG_CONTEXT_PMPORT_MASK;
493 }
494 printf("%s.%d: fatal error (%d), aborting active slots "
495 "(%08x) and resetting device.\n", PORTNAME(sp),
496 err_port, err_code, pss_saved);
497 while (pss_saved) {
498 slot = ffs(pss_saved) - 1;
499 pss_saved &= ~(1 << slot);
500
501 ccb = &sp->sp_ccbs[slot];
502 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
503 ccb->ccb_xa.state = ATA_S_ERROR;
504 }
505 need_restart = SILI_PREG_PCS_DEVRESET;
506 goto fatal;
507 }
508
509 DPRINTF(SILI_D_VERBOSE, "%s.%d: %serror, code %d, slot %d, "
510 "active %08x\n", PORTNAME(sp), err_port,
511 sactive ? "NCQ " : "", err_code, err_slot, sp->sp_active);
512
513 /* Clear the failed command in saved PSS so cmd_done runs. */
514 pss_saved &= ~(1 << err_slot);
515 /* Track errored commands until we finish recovery */
516 sp->sp_err_cmds |= (1 << err_slot);
517
518 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
519 ccb->ccb_xa.state = ATA_S_ERROR;
520
521 need_restart = SILI_PREG_PCS_PORTINIT;
522 }
523 fatal:
524
525 /* Process command timeout request only if command is still active. */
526 if (timeout_slot >= 0 && (pss_saved & (1 << timeout_slot))) {
527 DPRINTF(SILI_D_VERBOSE, "%s: timing out slot %d, active %08x\n",
528 PORTNAME(sp), timeout_slot, sp->sp_active);
529
530 /* Clear the failed command in saved PSS so cmd_done runs. */
531 pss_saved &= ~(1 << timeout_slot);
532
533 ccb = &sp->sp_ccbs[timeout_slot];
534 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
535 ccb->ccb_xa.state = ATA_S_TIMEOUT;
536
537 /* Reinitialise the port and clear all active commands */
538 need_restart = SILI_PREG_PCS_PORTINIT;
539
540 err_port = ccb->ccb_xa.pmp_port;
541 sp->sp_err_cmds |= (1 << timeout_slot);
542
543 sili_port_clear_commands(sp);
544 }
545
546 /* Command slot is complete if its bit in PSS is 0 but 1 in active. */
547 pss_masked = ~pss_saved & sp->sp_active;
548 while (pss_masked) {
549 slot = ffs(pss_masked) - 1;
550 ccb = &sp->sp_ccbs[slot];
551 pss_masked &= ~(1 << slot);
552
553 /* copy the rfis into the ccb if we were asked for it */
554 if (ccb->ccb_xa.state == ATA_S_ONCHIP &&
555 ccb->ccb_xa.flags & ATA_F_GET_RFIS) {
556 sili_pread_fis(sp, slot, &ccb->ccb_xa.rfis);
557 }
558
559 #ifdef SILI_ERROR_TEST
560 /* introduce random errors on reads and writes for testing */
561 sili_simulate_error(ccb, &need_restart, &err_port);
562 #endif
563
564 DPRINTF(SILI_D_INTR, "%s: slot %d is complete%s%s\n",
565 PORTNAME(sp), slot, ccb->ccb_xa.state == ATA_S_ERROR ?
566 " (error)" : (ccb->ccb_xa.state == ATA_S_TIMEOUT ?
567 " (timeout)" : ""),
568 ccb->ccb_xa.flags & ATA_F_NCQ ? " (ncq)" : "");
569
570 sili_ata_cmd_done(ccb, need_restart);
571
572 processed |= 1 << slot;
573
574 sili_pmp_port_do_error_recovery(sp, slot, &need_restart);
575 }
576
577 if (need_restart) {
578
579 if (sp->sp_pmp_error_recovery) {
580 if (sp->sp_err_active != 0) {
581 DPRINTF(SILI_D_VERBOSE, "%s: still waiting for "
582 "non-error commands to finish; port mask "
583 "%x, slot mask %x\n", PORTNAME(sp),
584 sp->sp_pmp_error_recovery,
585 sp->sp_err_active);
586 return (processed);
587 }
588 } else if (timeout_slot < 0 && sp->sp_pmp_ports > 0) {
589 /* wait until all other commands have finished before
590 * attempting to reinit the port.
591 */
592 DPRINTF(SILI_D_VERBOSE, "%s: error on port with PMP "
593 "attached, error port %d\n", PORTNAME(sp),
594 err_port);
595 if (sili_pmp_port_start_error_recovery(sp, err_port)) {
596 DPRINTF(SILI_D_VERBOSE, "%s: need to wait for "
597 "other commands to finish\n", PORTNAME(sp));
598 return (processed);
599 }
600 } else if (sp->sp_pmp_ports > 0) {
601 DPRINTF(SILI_D_VERBOSE, "%s: timeout on PMP port\n",
602 PORTNAME(sp));
603 } else {
604 DPRINTF(SILI_D_VERBOSE, "%s: error on non-PMP port\n",
605 PORTNAME(sp));
606 }
607
608 /* Re-enable transfers on port. */
609 sili_pwrite(sp, SILI_PREG_PCS, need_restart);
610 if (!sili_pwait_eq(sp, SILI_PREG_PCS, need_restart, 0, 5000)) {
611 printf("%s: port reset bit didn't clear after error\n",
612 PORTNAME(sp));
613 }
614 if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY,
615 SILI_PREG_PCS_PORTRDY, 1000)) {
616 printf("%s: couldn't restart port after error\n",
617 PORTNAME(sp));
618 }
619 sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_RESUME);
620
621 /* check that our active CCB list matches the restart mask */
622 pss_masked = pss_saved & ~(sp->sp_err_cmds);
623 DPRINTF(SILI_D_VERBOSE, "%s: restart mask %x\n",
624 PORTNAME(sp), pss_masked);
625 TAILQ_FOREACH(ccb, &sp->sp_active_ccbs, ccb_entry) {
626 if (!(pss_masked & (1 << ccb->ccb_xa.tag))) {
627 panic("sili_intr: slot %d not active in "
628 "pss_masked: %08x, state %02x",
629 ccb->ccb_xa.tag, pss_masked,
630 ccb->ccb_xa.state);
631 }
632 pss_masked &= ~(1 << ccb->ccb_xa.tag);
633 }
634 if (pss_masked != 0) {
635 printf("%s: mask excluding active slots: %x\n",
636 PORTNAME(sp), pss_masked);
637 }
638 KASSERT(pss_masked == 0);
639
640 /* if we had a timeout on a PMP port, do a portreset.
641 * exclude the control port here as there isn't a real
642 * device there to reset.
643 */
644 if (timeout_slot >= 0 && sp->sp_pmp_ports > 0 &&
645 err_port != 15) {
646
647 DPRINTF(SILI_D_VERBOSE,
648 "%s.%d: doing portreset after timeout\n",
649 PORTNAME(sp), err_port);
650 sili_pmp_portreset(sp->sp_sc, sp->sp_port, err_port);
651
652 /* wait a bit to let the port settle down */
653 delay(2000000);
654 }
655
656 /* if we sent a device reset to a PMP, we need to reset the
657 * devices behind it too.
658 */
659 if (need_restart == SILI_PREG_PCS_DEVRESET &&
660 sp->sp_pmp_ports > 0) {
661 int port_type;
662 int i;
663
664 port_type = sili_port_softreset(sp);
665 if (port_type != ATA_PORT_T_PM) {
666 /* device disappeared or changed type? */
667 printf("%s: expected to find a port multiplier,"
668 " got %d\n", PORTNAME(sp), port_type);
669 }
670
671 /* and now portreset all active ports */
672 for (i = 0; i < sp->sp_pmp_ports; i++) {
673 struct sili_softc *sc = sp->sp_sc;
674
675 if ((sp->sp_active_pmp_ports & (1 << i)) == 0)
676 continue;
677
678 if (sili_pmp_portreset(sc, sp->sp_port, i)) {
679 printf("%s.%d: failed to portreset "
680 "after error\n", PORTNAME(sp), i);
681 }
682 }
683 }
684
685 /* Restart CCBs in the order they were originally queued. */
686 TAILQ_FOREACH(ccb, &sp->sp_active_ccbs, ccb_entry) {
687 DPRINTF(SILI_D_VERBOSE, "%s: restarting slot %d "
688 "after error, state %02x\n", PORTNAME(sp),
689 ccb->ccb_xa.tag, ccb->ccb_xa.state);
690 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
691 sili_post_indirect(sp, ccb);
692 }
693 sp->sp_err_cmds = 0;
694 sp->sp_pmp_error_recovery = 0;
695
696 /*
697 * Finally, run atascsi completion for any finished CCBs. If
698 * we had run these during cmd_done above, any ccbs that their
699 * completion generated would have been activated out of order.
700 */
701 while ((ccb = TAILQ_FIRST(&sp->sp_deferred_ccbs)) != NULL) {
702 TAILQ_REMOVE(&sp->sp_deferred_ccbs, ccb, ccb_entry);
703
704 DPRINTF(SILI_D_VERBOSE, "%s: running deferred "
705 "completion for slot %d, state %02x\n",
706 PORTNAME(sp), ccb->ccb_xa.tag, ccb->ccb_xa.state);
707 KASSERT(ccb->ccb_xa.state == ATA_S_COMPLETE ||
708 ccb->ccb_xa.state == ATA_S_ERROR ||
709 ccb->ccb_xa.state == ATA_S_TIMEOUT);
710 ata_complete(&ccb->ccb_xa);
711 }
712 }
713
714 return (processed);
715 }
716
717 int
sili_intr(void * arg)718 sili_intr(void *arg)
719 {
720 struct sili_softc *sc = arg;
721 u_int32_t is;
722 int port;
723
724 /* If the card has gone away, this will return 0xffffffff. */
725 is = sili_read(sc, SILI_REG_GIS);
726 if (is == 0 || is == 0xffffffff)
727 return (0);
728 sili_write(sc, SILI_REG_GIS, is);
729 DPRINTF(SILI_D_INTR, "sili_intr, GIS: %08x\n", is);
730
731 while (is & SILI_REG_GIS_PIS_MASK) {
732 port = ffs(is) - 1;
733 sili_port_intr(&sc->sc_ports[port], -1);
734 is &= ~(1 << port);
735 }
736
737 return (1);
738 }
739
740 int
sili_ports_alloc(struct sili_softc * sc)741 sili_ports_alloc(struct sili_softc *sc)
742 {
743 struct sili_port *sp;
744 int i;
745
746 sc->sc_ports = mallocarray(sc->sc_nports, sizeof(struct sili_port),
747 M_DEVBUF, M_WAITOK | M_ZERO);
748
749 for (i = 0; i < sc->sc_nports; i++) {
750 sp = &sc->sc_ports[i];
751
752 sp->sp_sc = sc;
753 sp->sp_port = i;
754 #ifdef SILI_DEBUG
755 snprintf(sp->sp_name, sizeof(sp->sp_name), "%s.%d",
756 DEVNAME(sc), i);
757 #endif
758 if (bus_space_subregion(sc->sc_iot_port, sc->sc_ioh_port,
759 SILI_PORT_OFFSET(i), SILI_PORT_SIZE, &sp->sp_ioh) != 0) {
760 printf("%s: unable to create register window "
761 "for port %d\n", DEVNAME(sc), i);
762 goto freeports;
763 }
764 }
765
766 return (0);
767
768 freeports:
769 /* bus_space(9) says subregions dont have to be freed */
770 free(sc->sc_ports, M_DEVBUF, sc->sc_nports * sizeof(struct sili_port));
771 sc->sc_ports = NULL;
772 return (1);
773 }
774
775 void
sili_ports_free(struct sili_softc * sc)776 sili_ports_free(struct sili_softc *sc)
777 {
778 struct sili_port *sp;
779 int i;
780
781 for (i = 0; i < sc->sc_nports; i++) {
782 sp = &sc->sc_ports[i];
783
784 if (sp->sp_ccbs != NULL)
785 sili_ccb_free(sp);
786 }
787
788 /* bus_space(9) says subregions dont have to be freed */
789 free(sc->sc_ports, M_DEVBUF, sc->sc_nports * sizeof(struct sili_port));
790 sc->sc_ports = NULL;
791 }
792
793 int
sili_ccb_alloc(struct sili_port * sp)794 sili_ccb_alloc(struct sili_port *sp)
795 {
796 struct sili_softc *sc = sp->sp_sc;
797 struct sili_ccb *ccb;
798 struct sili_prb *prb;
799 int i;
800
801 TAILQ_INIT(&sp->sp_free_ccbs);
802 mtx_init(&sp->sp_free_ccb_mtx, IPL_BIO);
803 TAILQ_INIT(&sp->sp_active_ccbs);
804 TAILQ_INIT(&sp->sp_deferred_ccbs);
805
806 sp->sp_ccbs = mallocarray(SILI_MAX_CMDS, sizeof(struct sili_ccb),
807 M_DEVBUF, M_WAITOK);
808 sp->sp_cmds = sili_dmamem_alloc(sc, SILI_CMD_LEN * SILI_MAX_CMDS,
809 SILI_PRB_ALIGN);
810 if (sp->sp_cmds == NULL)
811 goto free_ccbs;
812 sp->sp_scratch = sili_dmamem_alloc(sc, SILI_SCRATCH_LEN, PAGE_SIZE);
813 if (sp->sp_scratch == NULL)
814 goto free_cmds;
815
816 bzero(sp->sp_ccbs, sizeof(struct sili_ccb) * SILI_MAX_CMDS);
817
818 for (i = 0; i < SILI_MAX_CMDS; i++) {
819 ccb = &sp->sp_ccbs[i];
820 ccb->ccb_port = sp;
821 ccb->ccb_cmd = SILI_DMA_KVA(sp->sp_cmds) + i * SILI_CMD_LEN;
822 ccb->ccb_cmd_dva = SILI_DMA_DVA(sp->sp_cmds) + i * SILI_CMD_LEN;
823 if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, SILI_DMA_SEGS,
824 MAXPHYS, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
825 &ccb->ccb_dmamap) != 0)
826 goto free_scratch;
827
828 prb = ccb->ccb_cmd;
829 ccb->ccb_xa.fis = (struct ata_fis_h2d *)&prb->fis;
830 ccb->ccb_xa.packetcmd = ((struct sili_prb_packet *)prb)->cdb;
831 ccb->ccb_xa.tag = i;
832 ccb->ccb_xa.state = ATA_S_COMPLETE;
833
834 sili_put_ccb(ccb);
835 }
836
837 return (0);
838
839 free_scratch:
840 sili_dmamem_free(sc, sp->sp_scratch);
841 free_cmds:
842 sili_dmamem_free(sc, sp->sp_cmds);
843 free_ccbs:
844 sili_ccb_free(sp);
845 return (1);
846 }
847
848 void
sili_ccb_free(struct sili_port * sp)849 sili_ccb_free(struct sili_port *sp)
850 {
851 struct sili_softc *sc = sp->sp_sc;
852 struct sili_ccb *ccb;
853
854 while ((ccb = sili_get_ccb(sp)) != NULL)
855 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
856
857 free(sp->sp_ccbs, M_DEVBUF, 0);
858 sp->sp_ccbs = NULL;
859 }
860
861 struct sili_ccb *
sili_get_ccb(struct sili_port * sp)862 sili_get_ccb(struct sili_port *sp)
863 {
864 struct sili_ccb *ccb;
865
866 /*
867 * Don't allow new commands to start while doing PMP error
868 * recovery
869 */
870 if (sp->sp_pmp_error_recovery != 0) {
871 return (NULL);
872 }
873
874 mtx_enter(&sp->sp_free_ccb_mtx);
875 ccb = TAILQ_FIRST(&sp->sp_free_ccbs);
876 if (ccb != NULL) {
877 KASSERT(ccb->ccb_xa.state == ATA_S_PUT);
878 TAILQ_REMOVE(&sp->sp_free_ccbs, ccb, ccb_entry);
879 ccb->ccb_xa.state = ATA_S_SETUP;
880 }
881 mtx_leave(&sp->sp_free_ccb_mtx);
882
883 return (ccb);
884 }
885
886 void
sili_put_ccb(struct sili_ccb * ccb)887 sili_put_ccb(struct sili_ccb *ccb)
888 {
889 struct sili_port *sp = ccb->ccb_port;
890
891 #ifdef DIAGNOSTIC
892 if (ccb->ccb_xa.state != ATA_S_COMPLETE &&
893 ccb->ccb_xa.state != ATA_S_TIMEOUT &&
894 ccb->ccb_xa.state != ATA_S_ERROR) {
895 printf("%s: invalid ata_xfer state %02x in sili_put_ccb, "
896 "slot %d\n", PORTNAME(sp), ccb->ccb_xa.state,
897 ccb->ccb_xa.tag);
898 }
899 #endif
900
901 ccb->ccb_xa.state = ATA_S_PUT;
902 mtx_enter(&sp->sp_free_ccb_mtx);
903 TAILQ_INSERT_TAIL(&sp->sp_free_ccbs, ccb, ccb_entry);
904 mtx_leave(&sp->sp_free_ccb_mtx);
905 }
906
907 struct sili_dmamem *
sili_dmamem_alloc(struct sili_softc * sc,bus_size_t size,bus_size_t align)908 sili_dmamem_alloc(struct sili_softc *sc, bus_size_t size, bus_size_t align)
909 {
910 struct sili_dmamem *sdm;
911 int nsegs;
912
913 sdm = malloc(sizeof(*sdm), M_DEVBUF, M_WAITOK | M_ZERO);
914 sdm->sdm_size = size;
915
916 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
917 BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &sdm->sdm_map) != 0)
918 goto sdmfree;
919
920 if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &sdm->sdm_seg,
921 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO) != 0)
922 goto destroy;
923
924 if (bus_dmamem_map(sc->sc_dmat, &sdm->sdm_seg, nsegs, size,
925 &sdm->sdm_kva, BUS_DMA_NOWAIT) != 0)
926 goto free;
927
928 if (bus_dmamap_load(sc->sc_dmat, sdm->sdm_map, sdm->sdm_kva, size,
929 NULL, BUS_DMA_NOWAIT) != 0)
930 goto unmap;
931
932 return (sdm);
933
934 unmap:
935 bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, size);
936 free:
937 bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1);
938 destroy:
939 bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map);
940 sdmfree:
941 free(sdm, M_DEVBUF, sizeof *sdm);
942
943 return (NULL);
944 }
945
946 void
sili_dmamem_free(struct sili_softc * sc,struct sili_dmamem * sdm)947 sili_dmamem_free(struct sili_softc *sc, struct sili_dmamem *sdm)
948 {
949 bus_dmamap_unload(sc->sc_dmat, sdm->sdm_map);
950 bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, sdm->sdm_size);
951 bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1);
952 bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map);
953 free(sdm, M_DEVBUF, sizeof *sdm);
954 }
955
956 u_int32_t
sili_read(struct sili_softc * sc,bus_size_t r)957 sili_read(struct sili_softc *sc, bus_size_t r)
958 {
959 u_int32_t rv;
960
961 bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4,
962 BUS_SPACE_BARRIER_READ);
963 rv = bus_space_read_4(sc->sc_iot_global, sc->sc_ioh_global, r);
964
965 return (rv);
966 }
967
968 void
sili_write(struct sili_softc * sc,bus_size_t r,u_int32_t v)969 sili_write(struct sili_softc *sc, bus_size_t r, u_int32_t v)
970 {
971 bus_space_write_4(sc->sc_iot_global, sc->sc_ioh_global, r, v);
972 bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4,
973 BUS_SPACE_BARRIER_WRITE);
974 }
975
976 u_int32_t
sili_pread(struct sili_port * sp,bus_size_t r)977 sili_pread(struct sili_port *sp, bus_size_t r)
978 {
979 u_int32_t rv;
980
981 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4,
982 BUS_SPACE_BARRIER_READ);
983 rv = bus_space_read_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r);
984
985 return (rv);
986 }
987
988 void
sili_pwrite(struct sili_port * sp,bus_size_t r,u_int32_t v)989 sili_pwrite(struct sili_port *sp, bus_size_t r, u_int32_t v)
990 {
991 bus_space_write_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, v);
992 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4,
993 BUS_SPACE_BARRIER_WRITE);
994 }
995
996 int
sili_pwait_eq(struct sili_port * sp,bus_size_t r,u_int32_t mask,u_int32_t value,int timeout)997 sili_pwait_eq(struct sili_port *sp, bus_size_t r, u_int32_t mask,
998 u_int32_t value, int timeout)
999 {
1000 while ((sili_pread(sp, r) & mask) != value) {
1001 if (timeout == 0)
1002 return (0);
1003
1004 delay(1000);
1005 timeout--;
1006 }
1007
1008 return (1);
1009 }
1010
1011 int
sili_pwait_ne(struct sili_port * sp,bus_size_t r,u_int32_t mask,u_int32_t value,int timeout)1012 sili_pwait_ne(struct sili_port *sp, bus_size_t r, u_int32_t mask,
1013 u_int32_t value, int timeout)
1014 {
1015 while ((sili_pread(sp, r) & mask) == value) {
1016 if (timeout == 0)
1017 return (0);
1018
1019 delay(1000);
1020 timeout--;
1021 }
1022
1023 return (1);
1024 }
1025
1026 void
sili_post_direct(struct sili_port * sp,u_int slot,void * buf,size_t buflen)1027 sili_post_direct(struct sili_port *sp, u_int slot, void *buf, size_t buflen)
1028 {
1029 bus_size_t r = SILI_PREG_SLOT(slot);
1030
1031 #ifdef DIAGNOSTIC
1032 if (buflen != 64 && buflen != 128)
1033 panic("sili_pcopy: buflen of %lu is not 64 or 128", buflen);
1034 #endif
1035
1036 bus_space_write_raw_region_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
1037 buf, buflen);
1038 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, buflen,
1039 BUS_SPACE_BARRIER_WRITE);
1040
1041 sili_pwrite(sp, SILI_PREG_FIFO, slot);
1042 }
1043
1044 void
sili_pread_fis(struct sili_port * sp,u_int slot,struct ata_fis_d2h * fis)1045 sili_pread_fis(struct sili_port *sp, u_int slot, struct ata_fis_d2h *fis)
1046 {
1047 bus_size_t r = SILI_PREG_SLOT(slot) + 8;
1048
1049 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
1050 sizeof(struct ata_fis_d2h), BUS_SPACE_BARRIER_READ);
1051 bus_space_read_raw_region_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
1052 fis, sizeof(struct ata_fis_d2h));
1053 }
1054
1055 void
sili_post_indirect(struct sili_port * sp,struct sili_ccb * ccb)1056 sili_post_indirect(struct sili_port *sp, struct sili_ccb *ccb)
1057 {
1058 sili_pwrite(sp, SILI_PREG_CAR_LO(ccb->ccb_xa.tag),
1059 (u_int32_t)ccb->ccb_cmd_dva);
1060 sili_pwrite(sp, SILI_PREG_CAR_HI(ccb->ccb_xa.tag),
1061 (u_int32_t)(ccb->ccb_cmd_dva >> 32));
1062 }
1063
1064 u_int32_t
sili_signature(struct sili_port * sp,u_int slot)1065 sili_signature(struct sili_port *sp, u_int slot)
1066 {
1067 u_int32_t sig_hi, sig_lo;
1068
1069 sig_hi = sili_pread(sp, SILI_PREG_SIG_HI(slot));
1070 sig_hi <<= SILI_PREG_SIG_HI_SHIFT;
1071 sig_lo = sili_pread(sp, SILI_PREG_SIG_LO(slot));
1072 sig_lo &= SILI_PREG_SIG_LO_MASK;
1073
1074 return (sig_hi | sig_lo);
1075 }
1076
1077 void
sili_dummy_done(struct ata_xfer * xa)1078 sili_dummy_done(struct ata_xfer *xa)
1079 {
1080 }
1081
1082 int
sili_pmp_portreset(struct sili_softc * sc,int port,int pmp_port)1083 sili_pmp_portreset(struct sili_softc *sc, int port, int pmp_port)
1084 {
1085 struct sili_port *sp;
1086 u_int32_t data;
1087 int loop;
1088
1089 sp = &sc->sc_ports[port];
1090 DPRINTF(SILI_D_VERBOSE, "%s: resetting pmp port %d\n", PORTNAME(sp),
1091 pmp_port);
1092
1093 if (sili_pmp_write(sp, pmp_port, SATA_PMREG_SERR, -1))
1094 goto err;
1095 if (sili_pmp_write(sp, pmp_port, SATA_PMREG_SCTL,
1096 SATA_PM_SCTL_IPM_DISABLED))
1097 goto err;
1098 delay(10000);
1099
1100 /* enable PHY by writing 1 then 0 to Scontrol DET field, using
1101 * Write Port Multiplier commands
1102 */
1103 data = SATA_PM_SCTL_IPM_DISABLED | SATA_PM_SCTL_DET_INIT |
1104 SATA_PM_SCTL_SPD_ANY;
1105 if (sili_pmp_write(sp, pmp_port, SATA_PMREG_SCTL, data))
1106 goto err;
1107 delay(100000);
1108
1109 if (sili_pmp_phy_status(sp, pmp_port, &data)) {
1110 printf("%s: cannot clear phy status for PMP probe\n",
1111 PORTNAME(sp));
1112 goto err;
1113 }
1114
1115 sili_pmp_write(sp, pmp_port, SATA_PMREG_SERR, -1);
1116 data = SATA_PM_SCTL_IPM_DISABLED | SATA_PM_SCTL_DET_NONE;
1117 if (sili_pmp_write(sp, pmp_port, SATA_PMREG_SCTL, data))
1118 goto err;
1119 delay(100000);
1120
1121 /* wait for PHYRDY by polling SStatus */
1122 for (loop = 3; loop; loop--) {
1123 if (sili_pmp_read(sp, pmp_port, SATA_PMREG_SSTS, &data))
1124 goto err;
1125 if (data & SATA_PM_SSTS_DET)
1126 break;
1127 delay(100000);
1128 }
1129 if (loop == 0) {
1130 DPRINTF(SILI_D_VERBOSE, "%s.%d: port appears to be unplugged\n",
1131 PORTNAME(sp), pmp_port);
1132 goto err;
1133 }
1134
1135 /* give it a bit more time to complete negotiation */
1136 for (loop = 30; loop; loop--) {
1137 if (sili_pmp_read(sp, pmp_port, SATA_PMREG_SSTS, &data))
1138 goto err;
1139 if ((data & SATA_PM_SSTS_DET) == SATA_PM_SSTS_DET_DEV)
1140 break;
1141 delay(10000);
1142 }
1143 if (loop == 0) {
1144 printf("%s.%d: device may be powered down\n", PORTNAME(sp),
1145 pmp_port);
1146 goto err;
1147 }
1148
1149 DPRINTF(SILI_D_VERBOSE, "%s.%d: device detected; SStatus=%08x\n",
1150 PORTNAME(sp), pmp_port, data);
1151
1152 /* clear the X-bit and all other error bits in Serror (PCSR[1]) */
1153 sili_pmp_write(sp, pmp_port, SATA_PMREG_SERR, -1);
1154 return (0);
1155
1156 err:
1157 DPRINTF(SILI_D_VERBOSE, "%s.%d: port reset failed\n", PORTNAME(sp),
1158 pmp_port);
1159 sili_pmp_write(sp, pmp_port, SATA_PMREG_SERR, -1);
1160 return (1);
1161 }
1162
1163 void
sili_pmp_op_timeout(void * cookie)1164 sili_pmp_op_timeout(void *cookie)
1165 {
1166 struct sili_ccb *ccb = cookie;
1167 struct sili_port *sp = ccb->ccb_port;
1168 int s;
1169
1170 switch (ccb->ccb_xa.state) {
1171 case ATA_S_PENDING:
1172 TAILQ_REMOVE(&sp->sp_active_ccbs, ccb, ccb_entry);
1173 ccb->ccb_xa.state = ATA_S_TIMEOUT;
1174 break;
1175 case ATA_S_ONCHIP:
1176 KASSERT(sp->sp_active == (1 << ccb->ccb_xa.tag));
1177 s = splbio();
1178 sili_port_intr(sp, ccb->ccb_xa.tag);
1179 splx(s);
1180 break;
1181 case ATA_S_ERROR:
1182 /* don't do anything? */
1183 break;
1184 default:
1185 panic("%s: sili_pmp_op_timeout: ccb in bad state %d",
1186 PORTNAME(sp), ccb->ccb_xa.state);
1187 }
1188 }
1189
1190 int
sili_pmp_softreset(struct sili_softc * sc,int port,int pmp_port)1191 sili_pmp_softreset(struct sili_softc *sc, int port, int pmp_port)
1192 {
1193 struct sili_ccb *ccb;
1194 struct sili_prb *prb;
1195 struct sili_port *sp;
1196 struct ata_fis_h2d *fis;
1197 u_int32_t data;
1198 u_int32_t signature;
1199
1200 sp = &sc->sc_ports[port];
1201
1202 ccb = sili_get_ccb(sp);
1203 if (ccb == NULL) {
1204 printf("%s: sili_pmp_softreset NULL ccb!\n", PORTNAME(sp));
1205 return (-1);
1206 }
1207
1208 ccb->ccb_xa.flags = ATA_F_POLL | ATA_F_GET_RFIS;
1209 ccb->ccb_xa.complete = sili_dummy_done;
1210 ccb->ccb_xa.pmp_port = pmp_port;
1211
1212 prb = ccb->ccb_cmd;
1213 bzero(prb, sizeof(*prb));
1214 fis = (struct ata_fis_h2d *)&prb->fis;
1215 fis->flags = pmp_port;
1216 prb->control = SILI_PRB_SOFT_RESET;
1217
1218 ccb->ccb_xa.state = ATA_S_PENDING;
1219
1220 if (sili_poll(ccb, 8000, sili_pmp_op_timeout) != 0) {
1221 DPRINTF(SILI_D_VERBOSE, "%s.%d: softreset FIS failed\n",
1222 PORTNAME(sp), pmp_port);
1223
1224 sili_put_ccb(ccb);
1225 /* don't return a valid device type here so the caller knows
1226 * it can retry if it wants to
1227 */
1228 return (-1);
1229 }
1230
1231 signature = ccb->ccb_xa.rfis.sector_count |
1232 (ccb->ccb_xa.rfis.lba_low << 8) |
1233 (ccb->ccb_xa.rfis.lba_mid << 16) |
1234 (ccb->ccb_xa.rfis.lba_high << 24);
1235 DPRINTF(SILI_D_VERBOSE, "%s.%d: signature: %08x\n", PORTNAME(sp),
1236 pmp_port, signature);
1237
1238 sili_put_ccb(ccb);
1239
1240 /* clear phy status and error bits */
1241 if (sili_pmp_phy_status(sp, pmp_port, &data)) {
1242 printf("%s.%d: cannot clear phy status after softreset\n",
1243 PORTNAME(sp), pmp_port);
1244 }
1245 sili_pmp_write(sp, pmp_port, SATA_PMREG_SERR, -1);
1246
1247 /* classify the device based on its signature */
1248 switch (signature) {
1249 case SATA_SIGNATURE_DISK:
1250 return (ATA_PORT_T_DISK);
1251 case SATA_SIGNATURE_ATAPI:
1252 return (ATA_PORT_T_ATAPI);
1253 case SATA_SIGNATURE_PORT_MULTIPLIER:
1254 return (ATA_PORT_T_NONE);
1255 default:
1256 return (ATA_PORT_T_NONE);
1257 }
1258 }
1259
1260 u_int32_t
sili_port_softreset(struct sili_port * sp)1261 sili_port_softreset(struct sili_port *sp)
1262 {
1263 struct sili_prb_softreset sreset;
1264 u_int32_t signature;
1265
1266 bzero(&sreset, sizeof(sreset));
1267 sreset.control = htole16(SILI_PRB_SOFT_RESET | SILI_PRB_INTERRUPT_MASK);
1268 sreset.fis[1] = SATA_PMP_CONTROL_PORT;
1269
1270 /* we use slot 0 */
1271 sili_post_direct(sp, 0, &sreset, sizeof(sreset));
1272 if (!sili_pwait_eq(sp, SILI_PREG_PSS, (1 << 0), 0, 1000)) {
1273 DPRINTF(SILI_D_VERBOSE, "%s: timed out while waiting for soft "
1274 "reset\n", PORTNAME(sp));
1275 return (ATA_PORT_T_NONE);
1276 }
1277
1278 /* Read device signature from command slot. */
1279 signature = sili_signature(sp, 0);
1280
1281 DPRINTF(SILI_D_VERBOSE, "%s: signature 0x%08x\n", PORTNAME(sp),
1282 signature);
1283
1284 switch (signature) {
1285 case SATA_SIGNATURE_DISK:
1286 return (ATA_PORT_T_DISK);
1287 case SATA_SIGNATURE_ATAPI:
1288 return (ATA_PORT_T_ATAPI);
1289 case SATA_SIGNATURE_PORT_MULTIPLIER:
1290 return (ATA_PORT_T_PM);
1291 default:
1292 return (ATA_PORT_T_NONE);
1293 }
1294 }
1295
1296 int
sili_ata_probe(void * xsc,int port,int lun)1297 sili_ata_probe(void *xsc, int port, int lun)
1298 {
1299 struct sili_softc *sc = xsc;
1300 struct sili_port *sp = &sc->sc_ports[port];
1301 int port_type;
1302
1303 /* handle pmp port probes */
1304 if (lun != 0) {
1305 int i;
1306 int rc;
1307 int pmp_port = lun - 1;
1308
1309 if (lun > sp->sp_pmp_ports)
1310 return (ATA_PORT_T_NONE);
1311
1312 for (i = 0; i < 2; i++) {
1313 if (sili_pmp_portreset(sc, port, pmp_port)) {
1314 continue;
1315 }
1316
1317 /* small delay between attempts to allow error
1318 * conditions to settle down. this doesn't seem
1319 * to affect portreset operations, just
1320 * commands sent to the device.
1321 */
1322 if (i != 0) {
1323 delay(5000000);
1324 }
1325
1326 rc = sili_pmp_softreset(sc, port, pmp_port);
1327 switch (rc) {
1328 case -1:
1329 /* possibly try again */
1330 break;
1331 case ATA_PORT_T_DISK:
1332 case ATA_PORT_T_ATAPI:
1333 /* mark this port as active */
1334 sp->sp_active_pmp_ports |= (1 << pmp_port);
1335 default:
1336 return (rc);
1337 }
1338 }
1339 DPRINTF(SILI_D_VERBOSE, "%s.%d: probe failed\n", PORTNAME(sp),
1340 pmp_port);
1341 return (ATA_PORT_T_NONE);
1342 }
1343
1344 sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRESET);
1345 delay(10000);
1346 sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_PORTRESET);
1347
1348 sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTINIT);
1349 if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY,
1350 SILI_PREG_PCS_PORTRDY, 1000)) {
1351 printf("%s: couldn't initialize port\n", PORTNAME(sp));
1352 return (ATA_PORT_T_NONE);
1353 }
1354
1355 sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_A32B);
1356
1357 if (!sili_pwait_eq(sp, SILI_PREG_SSTS, SATA_SStatus_DET,
1358 SATA_SStatus_DET_DEV, 2000)) {
1359 DPRINTF(SILI_D_VERBOSE, "%s: unattached\n", PORTNAME(sp));
1360 return (ATA_PORT_T_NONE);
1361 }
1362
1363 DPRINTF(SILI_D_VERBOSE, "%s: SSTS 0x%08x\n", PORTNAME(sp),
1364 sili_pread(sp, SILI_PREG_SSTS));
1365
1366 port_type = sili_port_softreset(sp);
1367 if (port_type == ATA_PORT_T_NONE)
1368 return (port_type);
1369
1370 /* allocate port resources */
1371 if (sili_ccb_alloc(sp) != 0)
1372 return (ATA_PORT_T_NONE);
1373
1374 /* do PMP probe now that we can talk to the device */
1375 if (port_type == ATA_PORT_T_PM) {
1376 int i;
1377
1378 sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PMEN);
1379
1380 if (sili_pmp_identify(sp, &sp->sp_pmp_ports)) {
1381 return (ATA_PORT_T_NONE);
1382 }
1383
1384 /* reset all the PMP ports to wake devices up */
1385 for (i = 0; i < sp->sp_pmp_ports; i++) {
1386 sili_pmp_portreset(sp->sp_sc, sp->sp_port, i);
1387 }
1388 }
1389
1390 /* enable port interrupts */
1391 sili_write(sc, SILI_REG_GC, sili_read(sc, SILI_REG_GC) | 1 << port);
1392 sili_pwrite(sp, SILI_PREG_IES, SILI_PREG_IE_CMDERR |
1393 SILI_PREG_IE_CMDCOMP);
1394
1395 return (port_type);
1396 }
1397
1398 void
sili_ata_free(void * xsc,int port,int lun)1399 sili_ata_free(void *xsc, int port, int lun)
1400 {
1401 struct sili_softc *sc = xsc;
1402 struct sili_port *sp = &sc->sc_ports[port];
1403
1404 if (lun == 0) {
1405 if (sp->sp_ccbs != NULL)
1406 sili_ccb_free(sp);
1407
1408 /* XXX we should do more here */
1409 }
1410 }
1411
1412 void
sili_ata_cmd(struct ata_xfer * xa)1413 sili_ata_cmd(struct ata_xfer *xa)
1414 {
1415 struct sili_ccb *ccb = (struct sili_ccb *)xa;
1416 struct sili_port *sp = ccb->ccb_port;
1417 struct sili_softc *sc = sp->sp_sc;
1418 struct sili_prb_ata *ata;
1419 struct sili_prb_packet *atapi;
1420 struct sili_sge *sgl;
1421 int sgllen;
1422 int s;
1423
1424 KASSERT(xa->state == ATA_S_SETUP || xa->state == ATA_S_TIMEOUT);
1425
1426 if (xa->flags & ATA_F_PACKET) {
1427 atapi = ccb->ccb_cmd;
1428
1429 if (xa->flags & ATA_F_WRITE)
1430 atapi->control = htole16(SILI_PRB_PACKET_WRITE);
1431 else
1432 atapi->control = htole16(SILI_PRB_PACKET_READ);
1433
1434 sgl = atapi->sgl;
1435 sgllen = nitems(atapi->sgl);
1436 } else {
1437 ata = ccb->ccb_cmd;
1438
1439 ata->control = 0;
1440
1441 sgl = ata->sgl;
1442 sgllen = nitems(ata->sgl);
1443 }
1444
1445 if (sili_load(ccb, sgl, sgllen) != 0)
1446 goto failcmd;
1447
1448 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_cmds),
1449 xa->tag * SILI_CMD_LEN, SILI_CMD_LEN, BUS_DMASYNC_PREWRITE);
1450
1451 timeout_set(&xa->stimeout, sili_ata_cmd_timeout, ccb);
1452
1453 xa->state = ATA_S_PENDING;
1454
1455 if (xa->flags & ATA_F_POLL)
1456 sili_poll(ccb, xa->timeout, sili_ata_cmd_timeout);
1457 else {
1458 s = splbio();
1459 timeout_add_msec(&xa->stimeout, xa->timeout);
1460 sili_start(sp, ccb);
1461 splx(s);
1462 }
1463
1464 return;
1465
1466 failcmd:
1467 s = splbio();
1468 xa->state = ATA_S_ERROR;
1469 ata_complete(xa);
1470 splx(s);
1471 }
1472
1473 void
sili_ata_cmd_done(struct sili_ccb * ccb,int defer_completion)1474 sili_ata_cmd_done(struct sili_ccb *ccb, int defer_completion)
1475 {
1476 struct sili_port *sp = ccb->ccb_port;
1477 struct sili_softc *sc = sp->sp_sc;
1478 struct ata_xfer *xa = &ccb->ccb_xa;
1479
1480 splassert(IPL_BIO);
1481
1482 timeout_del(&xa->stimeout);
1483
1484 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_cmds),
1485 xa->tag * SILI_CMD_LEN, SILI_CMD_LEN, BUS_DMASYNC_POSTWRITE);
1486
1487 sili_unload(ccb);
1488
1489 TAILQ_REMOVE(&sp->sp_active_ccbs, ccb, ccb_entry);
1490 sp->sp_active &= ~(1 << xa->tag);
1491 if (sp->sp_err_active & (1 << xa->tag)) {
1492 sp->sp_err_active &= ~(1 << xa->tag);
1493 DPRINTF(SILI_D_VERBOSE, "%s: slot %d complete, error mask now "
1494 "%x\n", PORTNAME(sp), xa->tag, sp->sp_err_active);
1495 }
1496
1497 if (xa->state == ATA_S_ONCHIP)
1498 xa->state = ATA_S_COMPLETE;
1499 #ifdef DIAGNOSTIC
1500 else if (xa->state != ATA_S_ERROR && xa->state != ATA_S_TIMEOUT)
1501 printf("%s: invalid ata_xfer state %02x in sili_ata_cmd_done, "
1502 "slot %d\n", PORTNAME(sp), xa->state, xa->tag);
1503 #endif
1504 if (defer_completion)
1505 TAILQ_INSERT_TAIL(&sp->sp_deferred_ccbs, ccb, ccb_entry);
1506 else if (xa->state == ATA_S_COMPLETE)
1507 ata_complete(xa);
1508 #ifdef DIAGNOSTIC
1509 else
1510 printf("%s: completion not deferred, but xa->state is %02x?\n",
1511 PORTNAME(sp), xa->state);
1512 #endif
1513 }
1514
1515 void
sili_ata_cmd_timeout(void * xccb)1516 sili_ata_cmd_timeout(void *xccb)
1517 {
1518 struct sili_ccb *ccb = xccb;
1519 struct sili_port *sp = ccb->ccb_port;
1520 int s;
1521
1522 s = splbio();
1523 sili_port_intr(sp, ccb->ccb_xa.tag);
1524 splx(s);
1525 }
1526
1527 int
sili_load(struct sili_ccb * ccb,struct sili_sge * sgl,int sgllen)1528 sili_load(struct sili_ccb *ccb, struct sili_sge *sgl, int sgllen)
1529 {
1530 struct sili_port *sp = ccb->ccb_port;
1531 struct sili_softc *sc = sp->sp_sc;
1532 struct ata_xfer *xa = &ccb->ccb_xa;
1533 struct sili_sge *nsge = sgl, *ce = NULL;
1534 bus_dmamap_t dmap = ccb->ccb_dmamap;
1535 u_int64_t addr;
1536 int error;
1537 int i;
1538
1539 if (xa->datalen == 0)
1540 return (0);
1541
1542 error = bus_dmamap_load(sc->sc_dmat, dmap, xa->data, xa->datalen, NULL,
1543 (xa->flags & ATA_F_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1544 if (error != 0) {
1545 printf("%s: error %d loading dmamap\n", PORTNAME(sp), error);
1546 return (1);
1547 }
1548
1549 if (dmap->dm_nsegs > sgllen)
1550 ce = &sgl[sgllen - 1];
1551
1552 for (i = 0; i < dmap->dm_nsegs; i++) {
1553 if (nsge == ce) {
1554 nsge++;
1555
1556 addr = ccb->ccb_cmd_dva;
1557 addr += ((u_int8_t *)nsge - (u_int8_t *)ccb->ccb_cmd);
1558
1559 ce->addr_lo = htole32((u_int32_t)addr);
1560 ce->addr_hi = htole32((u_int32_t)(addr >> 32));
1561 ce->flags = htole32(SILI_SGE_LNK);
1562
1563 if ((dmap->dm_nsegs - i) > SILI_SGT_SGLLEN)
1564 ce += SILI_SGT_SGLLEN;
1565 else
1566 ce = NULL;
1567 }
1568
1569 sgl = nsge;
1570
1571 addr = dmap->dm_segs[i].ds_addr;
1572 sgl->addr_lo = htole32((u_int32_t)addr);
1573 sgl->addr_hi = htole32((u_int32_t)(addr >> 32));
1574 sgl->data_count = htole32(dmap->dm_segs[i].ds_len);
1575 sgl->flags = 0;
1576
1577 nsge++;
1578 }
1579 sgl->flags |= htole32(SILI_SGE_TRM);
1580
1581 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
1582 (xa->flags & ATA_F_READ) ? BUS_DMASYNC_PREREAD :
1583 BUS_DMASYNC_PREWRITE);
1584
1585 return (0);
1586 }
1587
1588 void
sili_unload(struct sili_ccb * ccb)1589 sili_unload(struct sili_ccb *ccb)
1590 {
1591 struct sili_port *sp = ccb->ccb_port;
1592 struct sili_softc *sc = sp->sp_sc;
1593 struct ata_xfer *xa = &ccb->ccb_xa;
1594 bus_dmamap_t dmap = ccb->ccb_dmamap;
1595
1596 if (xa->datalen == 0)
1597 return;
1598
1599 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
1600 (xa->flags & ATA_F_READ) ? BUS_DMASYNC_POSTREAD :
1601 BUS_DMASYNC_POSTWRITE);
1602 bus_dmamap_unload(sc->sc_dmat, dmap);
1603
1604 if (xa->flags & ATA_F_READ)
1605 xa->resid = xa->datalen - sili_pread(sp,
1606 SILI_PREG_RX_COUNT(xa->tag));
1607 else
1608 xa->resid = 0;
1609 }
1610
1611 int
sili_poll(struct sili_ccb * ccb,int timeout,void (* timeout_fn)(void *))1612 sili_poll(struct sili_ccb *ccb, int timeout, void (*timeout_fn)(void *))
1613 {
1614 struct sili_port *sp = ccb->ccb_port;
1615 int s;
1616
1617 s = splbio();
1618 sili_start(sp, ccb);
1619 do {
1620 if (sili_port_intr(sp, -1) & (1 << ccb->ccb_xa.tag)) {
1621 splx(s);
1622 return (ccb->ccb_xa.state != ATA_S_COMPLETE);
1623 }
1624
1625 delay(1000);
1626 } while (--timeout > 0);
1627
1628 /* Run timeout while at splbio, otherwise sili_intr could interfere. */
1629 if (timeout_fn != NULL)
1630 timeout_fn(ccb);
1631
1632 splx(s);
1633
1634 return (1);
1635 }
1636
1637 void
sili_start(struct sili_port * sp,struct sili_ccb * ccb)1638 sili_start(struct sili_port *sp, struct sili_ccb *ccb)
1639 {
1640 int slot = ccb->ccb_xa.tag;
1641
1642 splassert(IPL_BIO);
1643 KASSERT(ccb->ccb_xa.state == ATA_S_PENDING);
1644 KASSERT(sp->sp_pmp_error_recovery == 0);
1645
1646 TAILQ_INSERT_TAIL(&sp->sp_active_ccbs, ccb, ccb_entry);
1647 sp->sp_active |= 1 << slot;
1648 ccb->ccb_xa.state = ATA_S_ONCHIP;
1649
1650 sili_post_indirect(sp, ccb);
1651 }
1652
1653 int
sili_read_ncq_error(struct sili_port * sp,int * err_slotp,int pmp_port)1654 sili_read_ncq_error(struct sili_port *sp, int *err_slotp, int pmp_port)
1655 {
1656 struct sili_softc *sc = sp->sp_sc;
1657 struct sili_prb_ata read_10h;
1658 u_int64_t addr;
1659 struct ata_fis_h2d *fis;
1660 struct ata_log_page_10h *log;
1661 struct sili_ccb *ccb;
1662 int rc;
1663
1664 sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTINIT);
1665 if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY,
1666 SILI_PREG_PCS_PORTRDY, 1000)) {
1667 printf("%s: couldn't ready port during log page read\n",
1668 PORTNAME(sp));
1669 return (1);
1670 }
1671
1672 /* READ LOG EXT 10h into scratch space */
1673 bzero(&read_10h, sizeof(read_10h));
1674 read_10h.control = htole16(SILI_PRB_INTERRUPT_MASK);
1675
1676 addr = SILI_DMA_DVA(sp->sp_scratch);
1677 read_10h.sgl[0].addr_lo = htole32((u_int32_t)addr);
1678 read_10h.sgl[0].addr_hi = htole32((u_int32_t)(addr >> 32));
1679 read_10h.sgl[0].data_count = htole32(512);
1680 read_10h.sgl[0].flags = htole32(SILI_SGE_TRM);
1681
1682 fis = (struct ata_fis_h2d *)read_10h.fis;
1683 fis->type = ATA_FIS_TYPE_H2D;
1684 fis->flags = ATA_H2D_FLAGS_CMD | pmp_port;
1685 fis->command = ATA_C_READ_LOG_EXT;
1686 fis->lba_low = 0x10; /* queued error log page (10h) */
1687 fis->sector_count = 1; /* number of sectors (1) */
1688 fis->sector_count_exp = 0;
1689 fis->lba_mid = 0; /* starting offset */
1690 fis->lba_mid_exp = 0;
1691 fis->device = 0;
1692
1693 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_scratch), 0,
1694 512, BUS_DMASYNC_PREREAD);
1695
1696 /* issue read and poll for completion */
1697 sili_post_direct(sp, 0, &read_10h, sizeof(read_10h));
1698 rc = sili_pwait_eq(sp, SILI_PREG_PSS, (1 << 0), 0, 1000);
1699
1700 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_scratch), 0,
1701 512, BUS_DMASYNC_POSTREAD);
1702
1703 if (!rc) {
1704 DPRINTF(SILI_D_VERBOSE, "%s: timed out while waiting for log "
1705 "page read\n", PORTNAME(sp));
1706 return (1);
1707 }
1708
1709 /* Extract failed register set and tags from the scratch space. */
1710 log = (struct ata_log_page_10h *)SILI_DMA_KVA(sp->sp_scratch);
1711 if (ISSET(log->err_regs.type, ATA_LOG_10H_TYPE_NOTQUEUED)) {
1712 /* Not queued bit was set - wasn't an NCQ error? */
1713 printf("%s: read NCQ error page, but not an NCQ error?\n",
1714 PORTNAME(sp));
1715 return (1);
1716 }
1717
1718 /* Copy back the log record as a D2H register FIS. */
1719 *err_slotp = log->err_regs.type & ATA_LOG_10H_TYPE_TAG_MASK;
1720
1721 ccb = &sp->sp_ccbs[*err_slotp];
1722 memcpy(&ccb->ccb_xa.rfis, &log->err_regs, sizeof(struct ata_fis_d2h));
1723 ccb->ccb_xa.rfis.type = ATA_FIS_TYPE_D2H;
1724 ccb->ccb_xa.rfis.flags = 0;
1725
1726 return (0);
1727 }
1728
1729 struct ata_xfer *
sili_ata_get_xfer(void * xsc,int port)1730 sili_ata_get_xfer(void *xsc, int port)
1731 {
1732 struct sili_softc *sc = xsc;
1733 struct sili_port *sp = &sc->sc_ports[port];
1734 struct sili_ccb *ccb;
1735
1736 ccb = sili_get_ccb(sp);
1737 if (ccb == NULL) {
1738 printf("%s: sili_ata_get_xfer NULL ccb!\n", PORTNAME(sp));
1739 return (NULL);
1740 }
1741
1742 bzero(ccb->ccb_cmd, SILI_CMD_LEN);
1743
1744 return ((struct ata_xfer *)ccb);
1745 }
1746
1747 void
sili_ata_put_xfer(struct ata_xfer * xa)1748 sili_ata_put_xfer(struct ata_xfer *xa)
1749 {
1750 struct sili_ccb *ccb = (struct sili_ccb *)xa;
1751
1752 sili_put_ccb(ccb);
1753 }
1754
1755 /* PMP register ops */
1756 int
sili_pmp_read(struct sili_port * sp,int target,int which,u_int32_t * datap)1757 sili_pmp_read(struct sili_port *sp, int target, int which, u_int32_t *datap)
1758 {
1759 struct sili_ccb *ccb;
1760 struct sili_prb *prb;
1761 struct ata_fis_h2d *fis;
1762 int error;
1763
1764 ccb = sili_get_ccb(sp);
1765 if (ccb == NULL) {
1766 printf("%s: sili_pmp_read NULL ccb!\n", PORTNAME(sp));
1767 return (1);
1768 }
1769 ccb->ccb_xa.flags = ATA_F_POLL | ATA_F_GET_RFIS;
1770 ccb->ccb_xa.complete = sili_dummy_done;
1771 ccb->ccb_xa.pmp_port = SATA_PMP_CONTROL_PORT;
1772 ccb->ccb_xa.state = ATA_S_PENDING;
1773
1774 prb = ccb->ccb_cmd;
1775 bzero(prb, sizeof(*prb));
1776 fis = (struct ata_fis_h2d *)&prb->fis;
1777 fis->type = ATA_FIS_TYPE_H2D;
1778 fis->flags = ATA_H2D_FLAGS_CMD | SATA_PMP_CONTROL_PORT;
1779 fis->command = ATA_C_READ_PM;
1780 fis->features = which;
1781 fis->device = target | ATA_H2D_DEVICE_LBA;
1782 fis->control = ATA_FIS_CONTROL_4BIT;
1783
1784 if (sili_poll(ccb, 1000, sili_pmp_op_timeout) != 0) {
1785 printf("sili_pmp_read(%d, %d) failed\n", target, which);
1786 error = 1;
1787 } else {
1788 *datap = ccb->ccb_xa.rfis.sector_count |
1789 (ccb->ccb_xa.rfis.lba_low << 8) |
1790 (ccb->ccb_xa.rfis.lba_mid << 16) |
1791 (ccb->ccb_xa.rfis.lba_high << 24);
1792 error = 0;
1793 }
1794 sili_put_ccb(ccb);
1795 return (error);
1796 }
1797
1798 int
sili_pmp_write(struct sili_port * sp,int target,int which,u_int32_t data)1799 sili_pmp_write(struct sili_port *sp, int target, int which, u_int32_t data)
1800 {
1801 struct sili_ccb *ccb;
1802 struct sili_prb *prb;
1803 struct ata_fis_h2d *fis;
1804 int error;
1805
1806 ccb = sili_get_ccb(sp);
1807 if (ccb == NULL) {
1808 printf("%s: sili_pmp_write NULL ccb!\n", PORTNAME(sp));
1809 return (1);
1810 }
1811 ccb->ccb_xa.complete = sili_dummy_done;
1812 ccb->ccb_xa.flags = ATA_F_POLL;
1813 ccb->ccb_xa.pmp_port = SATA_PMP_CONTROL_PORT;
1814 ccb->ccb_xa.state = ATA_S_PENDING;
1815
1816 prb = ccb->ccb_cmd;
1817 bzero(prb, sizeof(*prb));
1818 fis = (struct ata_fis_h2d *)&prb->fis;
1819 fis->type = ATA_FIS_TYPE_H2D;
1820 fis->flags = ATA_H2D_FLAGS_CMD | SATA_PMP_CONTROL_PORT;
1821 fis->command = ATA_C_WRITE_PM;
1822 fis->features = which;
1823 fis->device = target | ATA_H2D_DEVICE_LBA;
1824 fis->sector_count = (u_int8_t)data;
1825 fis->lba_low = (u_int8_t)(data >> 8);
1826 fis->lba_mid = (u_int8_t)(data >> 16);
1827 fis->lba_high = (u_int8_t)(data >> 24);
1828 fis->control = ATA_FIS_CONTROL_4BIT;
1829
1830 error = sili_poll(ccb, 1000, sili_pmp_op_timeout);
1831 sili_put_ccb(ccb);
1832 return (error);
1833 }
1834
1835 int
sili_pmp_phy_status(struct sili_port * sp,int target,u_int32_t * datap)1836 sili_pmp_phy_status(struct sili_port *sp, int target, u_int32_t *datap)
1837 {
1838 int error;
1839
1840 error = sili_pmp_read(sp, target, SATA_PMREG_SSTS, datap);
1841 if (error == 0)
1842 error = sili_pmp_write(sp, target, SATA_PMREG_SERR, -1);
1843 if (error)
1844 *datap = 0;
1845
1846 return (error);
1847 }
1848
1849 int
sili_pmp_identify(struct sili_port * sp,int * ret_nports)1850 sili_pmp_identify(struct sili_port *sp, int *ret_nports)
1851 {
1852 u_int32_t chipid;
1853 u_int32_t rev;
1854 u_int32_t nports;
1855 u_int32_t features;
1856 u_int32_t enabled;
1857
1858 if (sili_pmp_read(sp, 15, 0, &chipid) ||
1859 sili_pmp_read(sp, 15, 1, &rev) ||
1860 sili_pmp_read(sp, 15, 2, &nports) ||
1861 sili_pmp_read(sp, 15, SATA_PMREG_FEA, &features) ||
1862 sili_pmp_read(sp, 15, SATA_PMREG_FEAEN, &enabled)) {
1863 printf("%s: port multiplier identification failed\n",
1864 PORTNAME(sp));
1865 return (1);
1866 }
1867
1868 nports &= 0x0F;
1869
1870 /* ignore SEMB port on SiI3726 port multiplier chips */
1871 if (chipid == 0x37261095) {
1872 nports--;
1873 }
1874
1875 printf("%s: port multiplier found: chip=%08x rev=0x%b nports=%d, "
1876 "features: 0x%b, enabled: 0x%b\n", PORTNAME(sp), chipid, rev,
1877 SATA_PFMT_PM_REV, nports, features, SATA_PFMT_PM_FEA, enabled,
1878 SATA_PFMT_PM_FEA);
1879
1880 *ret_nports = nports;
1881 return (0);
1882 }
1883