1/*	$OpenBSD: sili.c,v 1.61 2022/04/09 20:10:26 naddy 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
44int 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
53int sili_error_pmp_ports = 0;		/* bitmask containing ports to fail*/
54int sili_error_test_inv_p = 500;	/* 1/P(error) */
55int sili_error_restart_type = SILI_PREG_PCS_PORTINIT; /* or _DEVRESET */
56
57struct cfdriver sili_cd = {
58	NULL, "sili", DV_DULL
59};
60
61/* wrapper around dma memory */
62struct 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
72struct sili_dmamem	*sili_dmamem_alloc(struct sili_softc *, bus_size_t,
73			    bus_size_t);
74void			sili_dmamem_free(struct sili_softc *,
75			    struct sili_dmamem *);
76
77/* per port goo */
78struct 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
83struct 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
113int			sili_ports_alloc(struct sili_softc *);
114void			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 cant 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
133struct 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
145int			sili_ccb_alloc(struct sili_port *);
146void			sili_ccb_free(struct sili_port *);
147struct sili_ccb		*sili_get_ccb(struct sili_port *);
148void			sili_put_ccb(struct sili_ccb *);
149
150/* bus space ops */
151u_int32_t		sili_read(struct sili_softc *, bus_size_t);
152void			sili_write(struct sili_softc *, bus_size_t, u_int32_t);
153u_int32_t		sili_pread(struct sili_port *, bus_size_t);
154void			sili_pwrite(struct sili_port *, bus_size_t, u_int32_t);
155int			sili_pwait_eq(struct sili_port *, bus_size_t,
156			    u_int32_t, u_int32_t, int);
157int			sili_pwait_ne(struct sili_port *, bus_size_t,
158			    u_int32_t, u_int32_t, int);
159
160/* command handling */
161void			sili_post_direct(struct sili_port *, u_int,
162			    void *, size_t buflen);
163void			sili_post_indirect(struct sili_port *,
164			    struct sili_ccb *);
165void			sili_pread_fis(struct sili_port *, u_int,
166			    struct ata_fis_d2h *);
167u_int32_t		sili_signature(struct sili_port *, u_int);
168u_int32_t		sili_port_softreset(struct sili_port *sp);
169int			sili_load(struct sili_ccb *, struct sili_sge *, int);
170void			sili_unload(struct sili_ccb *);
171int			sili_poll(struct sili_ccb *, int, void (*)(void *));
172void			sili_start(struct sili_port *, struct sili_ccb *);
173int			sili_read_ncq_error(struct sili_port *, int *, int);
174int			sili_pmp_port_start_error_recovery(struct sili_port *,
175			    int);
176void			sili_pmp_port_do_error_recovery(struct sili_port *,
177			    int, u_int32_t *);
178void			sili_port_clear_commands(struct sili_port *sp);
179
180/* pmp operations */
181int			sili_pmp_read(struct sili_port *, int, int,
182			    u_int32_t *);
183int			sili_pmp_write(struct sili_port *, int, int, u_int32_t);
184int			sili_pmp_phy_status(struct sili_port *, int,
185			    u_int32_t *);
186int 			sili_pmp_identify(struct sili_port *, int *);
187
188/* port interrupt handler */
189u_int32_t		sili_port_intr(struct sili_port *, int);
190
191/* atascsi interface */
192int			sili_ata_probe(void *, int, int);
193void			sili_ata_free(void *, int, int);
194struct ata_xfer		*sili_ata_get_xfer(void *, int);
195void			sili_ata_put_xfer(struct ata_xfer *);
196void			sili_ata_cmd(struct ata_xfer *);
197int			sili_pmp_portreset(struct sili_softc *, int, int);
198int			sili_pmp_softreset(struct sili_softc *, int, int);
199
200#ifdef SILI_ERROR_TEST
201void 			sili_simulate_error(struct sili_ccb *ccb,
202			    int *need_restart, int *err_port);
203#endif
204
205const 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 */
214void			sili_ata_cmd_done(struct sili_ccb *, int);
215void			sili_ata_cmd_timeout(void *);
216void			sili_dummy_done(struct ata_xfer *);
217
218void			sili_pmp_op_timeout(void *);
219
220int
221sili_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
249int
250sili_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
266void
267sili_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
285int
286sili_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
320void
321sili_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
339void
340sili_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
366void
367sili_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
402u_int32_t
403sili_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	}
523fatal:
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
717int
718sili_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
740int
741sili_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
768freeports:
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
775void
776sili_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
793int
794sili_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
839free_scratch:
840	sili_dmamem_free(sc, sp->sp_scratch);
841free_cmds:
842	sili_dmamem_free(sc, sp->sp_cmds);
843free_ccbs:
844	sili_ccb_free(sp);
845	return (1);
846}
847
848void
849sili_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
861struct sili_ccb *
862sili_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
886void
887sili_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
907struct sili_dmamem *
908sili_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
934unmap:
935	bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, size);
936free:
937	bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1);
938destroy:
939	bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map);
940sdmfree:
941	free(sdm, M_DEVBUF, sizeof *sdm);
942
943	return (NULL);
944}
945
946void
947sili_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
956u_int32_t
957sili_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
968void
969sili_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
976u_int32_t
977sili_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
988void
989sili_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
996int
997sili_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
1011int
1012sili_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
1026void
1027sili_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
1044void
1045sili_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
1055void
1056sili_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
1064u_int32_t
1065sili_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
1077void
1078sili_dummy_done(struct ata_xfer *xa)
1079{
1080}
1081
1082int
1083sili_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
1156err:
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
1163void
1164sili_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
1190int
1191sili_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
1260u_int32_t
1261sili_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
1296int
1297sili_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
1398void
1399sili_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
1412void
1413sili_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
1466failcmd:
1467	s = splbio();
1468	xa->state = ATA_S_ERROR;
1469	ata_complete(xa);
1470	splx(s);
1471}
1472
1473void
1474sili_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
1515void
1516sili_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
1527int
1528sili_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
1588void
1589sili_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
1611int
1612sili_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
1637void
1638sili_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
1653int
1654sili_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
1729struct ata_xfer *
1730sili_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
1747void
1748sili_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 */
1756int
1757sili_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
1798int
1799sili_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
1835int
1836sili_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
1849int
1850sili_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