xref: /freebsd/sys/dev/siis/siis.c (revision 4cca153030fd8932b30d1fee8ab1d698c75fcdae)
1 /*-
2  * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification, immediately at the beginning of the file.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/param.h>
31 #include <sys/module.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/ata.h>
35 #include <sys/bus.h>
36 #include <sys/endian.h>
37 #include <sys/malloc.h>
38 #include <sys/lock.h>
39 #include <sys/mutex.h>
40 #include <sys/sema.h>
41 #include <sys/taskqueue.h>
42 #include <vm/uma.h>
43 #include <machine/stdarg.h>
44 #include <machine/resource.h>
45 #include <machine/bus.h>
46 #include <sys/rman.h>
47 #include <dev/pci/pcivar.h>
48 #include <dev/pci/pcireg.h>
49 #include "siis.h"
50 
51 #include <cam/cam.h>
52 #include <cam/cam_ccb.h>
53 #include <cam/cam_sim.h>
54 #include <cam/cam_xpt_sim.h>
55 #include <cam/cam_debug.h>
56 
57 /* local prototypes */
58 static int siis_setup_interrupt(device_t dev);
59 static void siis_intr(void *data);
60 static int siis_suspend(device_t dev);
61 static int siis_resume(device_t dev);
62 static int siis_ch_suspend(device_t dev);
63 static int siis_ch_resume(device_t dev);
64 static void siis_ch_intr_locked(void *data);
65 static void siis_ch_intr(void *data);
66 static void siis_begin_transaction(device_t dev, union ccb *ccb);
67 static void siis_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error);
68 static void siis_execute_transaction(struct siis_slot *slot);
69 static void siis_timeout(struct siis_slot *slot);
70 static void siis_end_transaction(struct siis_slot *slot, enum siis_err_type et);
71 static int siis_setup_fis(device_t dev, struct siis_cmd *ctp, union ccb *ccb, int tag);
72 static void siis_dmainit(device_t dev);
73 static void siis_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
74 static void siis_dmafini(device_t dev);
75 static void siis_slotsalloc(device_t dev);
76 static void siis_slotsfree(device_t dev);
77 static void siis_reset(device_t dev);
78 static void siis_portinit(device_t dev);
79 static int siis_wait_ready(device_t dev, int t);
80 
81 static int siis_sata_connect(struct siis_channel *ch);
82 
83 static void siis_issue_read_log(device_t dev);
84 static void siis_process_read_log(device_t dev, union ccb *ccb);
85 
86 static void siisaction(struct cam_sim *sim, union ccb *ccb);
87 static void siispoll(struct cam_sim *sim);
88 
89 MALLOC_DEFINE(M_SIIS, "SIIS driver", "SIIS driver data buffers");
90 
91 static struct {
92 	uint32_t	id;
93 	const char	*name;
94 	int		ports;
95 	int		quirks;
96 #define SIIS_Q_SNTF	1
97 } siis_ids[] = {
98 	{0x31241095,	"SiI3124",	4,	0},
99 	{0x31248086,	"SiI3124",	4,	0},
100 	{0x31321095,	"SiI3132",	2,	SIIS_Q_SNTF},
101 	{0x02421095,	"SiI3132",	2,	SIIS_Q_SNTF},
102 	{0x02441095,	"SiI3132",	2,	SIIS_Q_SNTF},
103 	{0x31311095,	"SiI3131",	1,	SIIS_Q_SNTF},
104 	{0x35311095,	"SiI3531",	1,	SIIS_Q_SNTF},
105 	{0,		NULL,		0,	0}
106 };
107 
108 static int
109 siis_probe(device_t dev)
110 {
111 	char buf[64];
112 	int i;
113 	uint32_t devid = pci_get_devid(dev);
114 
115 	for (i = 0; siis_ids[i].id != 0; i++) {
116 		if (siis_ids[i].id == devid) {
117 			snprintf(buf, sizeof(buf), "%s SATA controller",
118 			    siis_ids[i].name);
119 			device_set_desc_copy(dev, buf);
120 			return (BUS_PROBE_VENDOR);
121 		}
122 	}
123 	return (ENXIO);
124 }
125 
126 static int
127 siis_attach(device_t dev)
128 {
129 	struct siis_controller *ctlr = device_get_softc(dev);
130 	uint32_t devid = pci_get_devid(dev);
131 	device_t child;
132 	int	error, i, unit;
133 
134 	ctlr->dev = dev;
135 	for (i = 0; siis_ids[i].id != 0; i++) {
136 		if (siis_ids[i].id == devid)
137 			break;
138 	}
139 	ctlr->quirks = siis_ids[i].quirks;
140 	/* Global memory */
141 	ctlr->r_grid = PCIR_BAR(0);
142 	if (!(ctlr->r_gmem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
143 	    &ctlr->r_grid, RF_ACTIVE)))
144 		return (ENXIO);
145 	ctlr->gctl = ATA_INL(ctlr->r_gmem, SIIS_GCTL);
146 	/* Channels memory */
147 	ctlr->r_rid = PCIR_BAR(2);
148 	if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
149 	    &ctlr->r_rid, RF_ACTIVE)))
150 		return (ENXIO);
151 	/* Setup our own memory management for channels. */
152 	ctlr->sc_iomem.rm_type = RMAN_ARRAY;
153 	ctlr->sc_iomem.rm_descr = "I/O memory addresses";
154 	if ((error = rman_init(&ctlr->sc_iomem)) != 0) {
155 		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
156 		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_grid, ctlr->r_gmem);
157 		return (error);
158 	}
159 	if ((error = rman_manage_region(&ctlr->sc_iomem,
160 	    rman_get_start(ctlr->r_mem), rman_get_end(ctlr->r_mem))) != 0) {
161 		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
162 		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_grid, ctlr->r_gmem);
163 		rman_fini(&ctlr->sc_iomem);
164 		return (error);
165 	}
166 	/* Reset controller */
167 	siis_resume(dev);
168 	/* Number of HW channels */
169 	ctlr->channels = siis_ids[i].ports;
170 	/* Setup interrupts. */
171 	if (siis_setup_interrupt(dev)) {
172 		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
173 		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_grid, ctlr->r_gmem);
174 		rman_fini(&ctlr->sc_iomem);
175 		return ENXIO;
176 	}
177 	/* Attach all channels on this controller */
178 	for (unit = 0; unit < ctlr->channels; unit++) {
179 		child = device_add_child(dev, "siisch", -1);
180 		if (child == NULL)
181 			device_printf(dev, "failed to add channel device\n");
182 		else
183 			device_set_ivars(child, (void *)(intptr_t)unit);
184 	}
185 	bus_generic_attach(dev);
186 	return 0;
187 }
188 
189 static int
190 siis_detach(device_t dev)
191 {
192 	struct siis_controller *ctlr = device_get_softc(dev);
193 	device_t *children;
194 	int nchildren, i;
195 
196 	/* Detach & delete all children */
197 	if (!device_get_children(dev, &children, &nchildren)) {
198 		for (i = 0; i < nchildren; i++)
199 			device_delete_child(dev, children[i]);
200 		free(children, M_TEMP);
201 	}
202 	/* Free interrupts. */
203 	if (ctlr->irq.r_irq) {
204 		bus_teardown_intr(dev, ctlr->irq.r_irq,
205 		    ctlr->irq.handle);
206 		bus_release_resource(dev, SYS_RES_IRQ,
207 		    ctlr->irq.r_irq_rid, ctlr->irq.r_irq);
208 	}
209 	pci_release_msi(dev);
210 	/* Free memory. */
211 	rman_fini(&ctlr->sc_iomem);
212 	bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
213 	bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_grid, ctlr->r_gmem);
214 	return (0);
215 }
216 
217 static int
218 siis_suspend(device_t dev)
219 {
220 	struct siis_controller *ctlr = device_get_softc(dev);
221 
222 	bus_generic_suspend(dev);
223 	/* Put controller into reset state. */
224 	ctlr->gctl |= SIIS_GCTL_GRESET;
225 	ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, ctlr->gctl);
226 	return 0;
227 }
228 
229 static int
230 siis_resume(device_t dev)
231 {
232 	struct siis_controller *ctlr = device_get_softc(dev);
233 	int cap;
234 	uint16_t val;
235 
236 	/* Set PCIe max read request size to at least 1024 bytes */
237 	if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) == 0) {
238 		val = pci_read_config(dev,
239 		    cap + PCIR_EXPRESS_DEVICE_CTL, 2);
240 		if ((val & PCIM_EXP_CTL_MAX_READ_REQUEST) < 0x3000) {
241 			val &= ~PCIM_EXP_CTL_MAX_READ_REQUEST;
242 			val |= 0x3000;
243 			pci_write_config(dev,
244 			    cap + PCIR_EXPRESS_DEVICE_CTL, val, 2);
245 		}
246 	}
247 	/* Put controller into reset state. */
248 	ctlr->gctl |= SIIS_GCTL_GRESET;
249 	ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, ctlr->gctl);
250 	DELAY(10000);
251 	/* Get controller out of reset state and enable port interrupts. */
252 	ctlr->gctl &= ~(SIIS_GCTL_GRESET | SIIS_GCTL_I2C_IE);
253 	ctlr->gctl |= 0x0000000f;
254 	ATA_OUTL(ctlr->r_gmem, SIIS_GCTL, ctlr->gctl);
255 	return (bus_generic_resume(dev));
256 }
257 
258 static int
259 siis_setup_interrupt(device_t dev)
260 {
261 	struct siis_controller *ctlr = device_get_softc(dev);
262 	int msi = 0;
263 
264 	/* Process hints. */
265 	resource_int_value(device_get_name(dev),
266 	    device_get_unit(dev), "msi", &msi);
267 	if (msi < 0)
268 		msi = 0;
269 	else if (msi > 0)
270 		msi = min(1, pci_msi_count(dev));
271 	/* Allocate MSI if needed/present. */
272 	if (msi && pci_alloc_msi(dev, &msi) != 0)
273 		msi = 0;
274 	/* Allocate all IRQs. */
275 	ctlr->irq.r_irq_rid = msi ? 1 : 0;
276 	if (!(ctlr->irq.r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
277 	    &ctlr->irq.r_irq_rid, RF_SHAREABLE | RF_ACTIVE))) {
278 		device_printf(dev, "unable to map interrupt\n");
279 		return ENXIO;
280 	}
281 	if ((bus_setup_intr(dev, ctlr->irq.r_irq, ATA_INTR_FLAGS, NULL,
282 	    siis_intr, ctlr, &ctlr->irq.handle))) {
283 		/* SOS XXX release r_irq */
284 		device_printf(dev, "unable to setup interrupt\n");
285 		return ENXIO;
286 	}
287 	return (0);
288 }
289 
290 /*
291  * Common case interrupt handler.
292  */
293 static void
294 siis_intr(void *data)
295 {
296 	struct siis_controller *ctlr = (struct siis_controller *)data;
297 	u_int32_t is;
298 	void *arg;
299 	int unit;
300 
301 	is = ATA_INL(ctlr->r_gmem, SIIS_IS);
302 	for (unit = 0; unit < ctlr->channels; unit++) {
303 		if ((is & SIIS_IS_PORT(unit)) != 0 &&
304 		    (arg = ctlr->interrupt[unit].argument)) {
305 			ctlr->interrupt[unit].function(arg);
306 		}
307 	}
308 	/* Acknowledge interrupt, if MSI enabled. */
309 	if (ctlr->irq.r_irq_rid) {
310 		ATA_OUTL(ctlr->r_gmem, SIIS_GCTL,
311 		    ctlr->gctl | SIIS_GCTL_MSIACK);
312 	}
313 }
314 
315 static struct resource *
316 siis_alloc_resource(device_t dev, device_t child, int type, int *rid,
317 		       u_long start, u_long end, u_long count, u_int flags)
318 {
319 	struct siis_controller *ctlr = device_get_softc(dev);
320 	int unit = ((struct siis_channel *)device_get_softc(child))->unit;
321 	struct resource *res = NULL;
322 	int offset = unit << 13;
323 	long st;
324 
325 	switch (type) {
326 	case SYS_RES_MEMORY:
327 		st = rman_get_start(ctlr->r_mem);
328 		res = rman_reserve_resource(&ctlr->sc_iomem, st + offset,
329 		    st + offset + 0x2000, 0x2000, RF_ACTIVE, child);
330 		if (res) {
331 			bus_space_handle_t bsh;
332 			bus_space_tag_t bst;
333 			bsh = rman_get_bushandle(ctlr->r_mem);
334 			bst = rman_get_bustag(ctlr->r_mem);
335 			bus_space_subregion(bst, bsh, offset, 0x2000, &bsh);
336 			rman_set_bushandle(res, bsh);
337 			rman_set_bustag(res, bst);
338 		}
339 		break;
340 	case SYS_RES_IRQ:
341 		if (*rid == ATA_IRQ_RID)
342 			res = ctlr->irq.r_irq;
343 		break;
344 	}
345 	return (res);
346 }
347 
348 static int
349 siis_release_resource(device_t dev, device_t child, int type, int rid,
350 			 struct resource *r)
351 {
352 
353 	switch (type) {
354 	case SYS_RES_MEMORY:
355 		rman_release_resource(r);
356 		return (0);
357 	case SYS_RES_IRQ:
358 		if (rid != ATA_IRQ_RID)
359 			return ENOENT;
360 		return (0);
361 	}
362 	return (EINVAL);
363 }
364 
365 static int
366 siis_setup_intr(device_t dev, device_t child, struct resource *irq,
367 		   int flags, driver_filter_t *filter, driver_intr_t *function,
368 		   void *argument, void **cookiep)
369 {
370 	struct siis_controller *ctlr = device_get_softc(dev);
371 	int unit = (intptr_t)device_get_ivars(child);
372 
373 	if (filter != NULL) {
374 		printf("siis.c: we cannot use a filter here\n");
375 		return (EINVAL);
376 	}
377 	ctlr->interrupt[unit].function = function;
378 	ctlr->interrupt[unit].argument = argument;
379 	return (0);
380 }
381 
382 static int
383 siis_teardown_intr(device_t dev, device_t child, struct resource *irq,
384 		      void *cookie)
385 {
386 	struct siis_controller *ctlr = device_get_softc(dev);
387 	int unit = (intptr_t)device_get_ivars(child);
388 
389 	ctlr->interrupt[unit].function = NULL;
390 	ctlr->interrupt[unit].argument = NULL;
391 	return (0);
392 }
393 
394 static int
395 siis_print_child(device_t dev, device_t child)
396 {
397 	int retval;
398 
399 	retval = bus_print_child_header(dev, child);
400 	retval += printf(" at channel %d",
401 	    (int)(intptr_t)device_get_ivars(child));
402 	retval += bus_print_child_footer(dev, child);
403 
404 	return (retval);
405 }
406 
407 devclass_t siis_devclass;
408 static device_method_t siis_methods[] = {
409 	DEVMETHOD(device_probe,     siis_probe),
410 	DEVMETHOD(device_attach,    siis_attach),
411 	DEVMETHOD(device_detach,    siis_detach),
412 	DEVMETHOD(device_suspend,   siis_suspend),
413 	DEVMETHOD(device_resume,    siis_resume),
414 	DEVMETHOD(bus_print_child,  siis_print_child),
415 	DEVMETHOD(bus_alloc_resource,       siis_alloc_resource),
416 	DEVMETHOD(bus_release_resource,     siis_release_resource),
417 	DEVMETHOD(bus_setup_intr,   siis_setup_intr),
418 	DEVMETHOD(bus_teardown_intr,siis_teardown_intr),
419 	{ 0, 0 }
420 };
421 static driver_t siis_driver = {
422         "siis",
423         siis_methods,
424         sizeof(struct siis_controller)
425 };
426 DRIVER_MODULE(siis, pci, siis_driver, siis_devclass, 0, 0);
427 MODULE_VERSION(siis, 1);
428 MODULE_DEPEND(siis, cam, 1, 1, 1);
429 
430 static int
431 siis_ch_probe(device_t dev)
432 {
433 
434 	device_set_desc_copy(dev, "SIIS channel");
435 	return (0);
436 }
437 
438 static int
439 siis_ch_attach(device_t dev)
440 {
441 	struct siis_controller *ctlr = device_get_softc(device_get_parent(dev));
442 	struct siis_channel *ch = device_get_softc(dev);
443 	struct cam_devq *devq;
444 	int rid, error, i, sata_rev = 0;
445 
446 	ch->dev = dev;
447 	ch->unit = (intptr_t)device_get_ivars(dev);
448 	ch->quirks = ctlr->quirks;
449 	resource_int_value(device_get_name(dev),
450 	    device_get_unit(dev), "pm_level", &ch->pm_level);
451 	resource_int_value(device_get_name(dev),
452 	    device_get_unit(dev), "sata_rev", &sata_rev);
453 	for (i = 0; i < 16; i++) {
454 		ch->user[i].revision = sata_rev;
455 		ch->user[i].mode = 0;
456 		ch->user[i].bytecount = 8192;
457 		ch->user[i].tags = SIIS_MAX_SLOTS;
458 		ch->curr[i] = ch->user[i];
459 	}
460 	mtx_init(&ch->mtx, "SIIS channel lock", NULL, MTX_DEF);
461 	rid = ch->unit;
462 	if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
463 	    &rid, RF_ACTIVE)))
464 		return (ENXIO);
465 	siis_dmainit(dev);
466 	siis_slotsalloc(dev);
467 	siis_ch_resume(dev);
468 	mtx_lock(&ch->mtx);
469 	rid = ATA_IRQ_RID;
470 	if (!(ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
471 	    &rid, RF_SHAREABLE | RF_ACTIVE))) {
472 		bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
473 		device_printf(dev, "Unable to map interrupt\n");
474 		return (ENXIO);
475 	}
476 	if ((bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, NULL,
477 	    siis_ch_intr_locked, dev, &ch->ih))) {
478 		device_printf(dev, "Unable to setup interrupt\n");
479 		error = ENXIO;
480 		goto err1;
481 	}
482 	/* Create the device queue for our SIM. */
483 	devq = cam_simq_alloc(SIIS_MAX_SLOTS);
484 	if (devq == NULL) {
485 		device_printf(dev, "Unable to allocate simq\n");
486 		error = ENOMEM;
487 		goto err1;
488 	}
489 	/* Construct SIM entry */
490 	ch->sim = cam_sim_alloc(siisaction, siispoll, "siisch", ch,
491 	    device_get_unit(dev), &ch->mtx, 2, SIIS_MAX_SLOTS, devq);
492 	if (ch->sim == NULL) {
493 		device_printf(dev, "unable to allocate sim\n");
494 		error = ENOMEM;
495 		goto err2;
496 	}
497 	if (xpt_bus_register(ch->sim, dev, 0) != CAM_SUCCESS) {
498 		device_printf(dev, "unable to register xpt bus\n");
499 		error = ENXIO;
500 		goto err2;
501 	}
502 	if (xpt_create_path(&ch->path, /*periph*/NULL, cam_sim_path(ch->sim),
503 	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
504 		device_printf(dev, "unable to create path\n");
505 		error = ENXIO;
506 		goto err3;
507 	}
508 	mtx_unlock(&ch->mtx);
509 	return (0);
510 
511 err3:
512 	xpt_bus_deregister(cam_sim_path(ch->sim));
513 err2:
514 	cam_sim_free(ch->sim, /*free_devq*/TRUE);
515 err1:
516 	bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
517 	bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
518 	mtx_unlock(&ch->mtx);
519 	return (error);
520 }
521 
522 static int
523 siis_ch_detach(device_t dev)
524 {
525 	struct siis_channel *ch = device_get_softc(dev);
526 
527 	mtx_lock(&ch->mtx);
528 	xpt_async(AC_LOST_DEVICE, ch->path, NULL);
529 	xpt_free_path(ch->path);
530 	xpt_bus_deregister(cam_sim_path(ch->sim));
531 	cam_sim_free(ch->sim, /*free_devq*/TRUE);
532 	mtx_unlock(&ch->mtx);
533 
534 	bus_teardown_intr(dev, ch->r_irq, ch->ih);
535 	bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
536 
537 	siis_ch_suspend(dev);
538 	siis_slotsfree(dev);
539 	siis_dmafini(dev);
540 
541 	bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
542 	mtx_destroy(&ch->mtx);
543 	return (0);
544 }
545 
546 static int
547 siis_ch_suspend(device_t dev)
548 {
549 	struct siis_channel *ch = device_get_softc(dev);
550 
551 	/* Put port into reset state. */
552 	ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PORT_RESET);
553 	return (0);
554 }
555 
556 static int
557 siis_ch_resume(device_t dev)
558 {
559 	struct siis_channel *ch = device_get_softc(dev);
560 
561 	/* Get port out of reset state. */
562 	ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PORT_RESET);
563 	ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_32BIT);
564 	if (ch->pm_present)
565 		ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME);
566 	else
567 		ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME);
568 	/* Enable port interrupts */
569 	ATA_OUTL(ch->r_mem, SIIS_P_IESET, SIIS_P_IX_ENABLED);
570 	return (0);
571 }
572 
573 devclass_t siisch_devclass;
574 static device_method_t siisch_methods[] = {
575 	DEVMETHOD(device_probe,     siis_ch_probe),
576 	DEVMETHOD(device_attach,    siis_ch_attach),
577 	DEVMETHOD(device_detach,    siis_ch_detach),
578 	DEVMETHOD(device_suspend,   siis_ch_suspend),
579 	DEVMETHOD(device_resume,    siis_ch_resume),
580 	{ 0, 0 }
581 };
582 static driver_t siisch_driver = {
583         "siisch",
584         siisch_methods,
585         sizeof(struct siis_channel)
586 };
587 DRIVER_MODULE(siisch, siis, siisch_driver, siis_devclass, 0, 0);
588 
589 struct siis_dc_cb_args {
590 	bus_addr_t maddr;
591 	int error;
592 };
593 
594 static void
595 siis_dmainit(device_t dev)
596 {
597 	struct siis_channel *ch = device_get_softc(dev);
598 	struct siis_dc_cb_args dcba;
599 
600 	/* Command area. */
601 	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1024, 0,
602 	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
603 	    NULL, NULL, SIIS_WORK_SIZE, 1, SIIS_WORK_SIZE,
604 	    0, NULL, NULL, &ch->dma.work_tag))
605 		goto error;
606 	if (bus_dmamem_alloc(ch->dma.work_tag, (void **)&ch->dma.work, 0,
607 	    &ch->dma.work_map))
608 		goto error;
609 	if (bus_dmamap_load(ch->dma.work_tag, ch->dma.work_map, ch->dma.work,
610 	    SIIS_WORK_SIZE, siis_dmasetupc_cb, &dcba, 0) || dcba.error) {
611 		bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map);
612 		goto error;
613 	}
614 	ch->dma.work_bus = dcba.maddr;
615 	/* Data area. */
616 	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
617 	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
618 	    NULL, NULL,
619 	    SIIS_SG_ENTRIES * PAGE_SIZE * SIIS_MAX_SLOTS,
620 	    SIIS_SG_ENTRIES, 0xFFFFFFFF,
621 	    0, busdma_lock_mutex, &ch->mtx, &ch->dma.data_tag)) {
622 		goto error;
623 	}
624 	return;
625 
626 error:
627 	device_printf(dev, "WARNING - DMA initialization failed\n");
628 	siis_dmafini(dev);
629 }
630 
631 static void
632 siis_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
633 {
634 	struct siis_dc_cb_args *dcba = (struct siis_dc_cb_args *)xsc;
635 
636 	if (!(dcba->error = error))
637 		dcba->maddr = segs[0].ds_addr;
638 }
639 
640 static void
641 siis_dmafini(device_t dev)
642 {
643 	struct siis_channel *ch = device_get_softc(dev);
644 
645 	if (ch->dma.data_tag) {
646 		bus_dma_tag_destroy(ch->dma.data_tag);
647 		ch->dma.data_tag = NULL;
648 	}
649 	if (ch->dma.work_bus) {
650 		bus_dmamap_unload(ch->dma.work_tag, ch->dma.work_map);
651 		bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map);
652 		ch->dma.work_bus = 0;
653 		ch->dma.work_map = NULL;
654 		ch->dma.work = NULL;
655 	}
656 	if (ch->dma.work_tag) {
657 		bus_dma_tag_destroy(ch->dma.work_tag);
658 		ch->dma.work_tag = NULL;
659 	}
660 }
661 
662 static void
663 siis_slotsalloc(device_t dev)
664 {
665 	struct siis_channel *ch = device_get_softc(dev);
666 	int i;
667 
668 	/* Alloc and setup command/dma slots */
669 	bzero(ch->slot, sizeof(ch->slot));
670 	for (i = 0; i < SIIS_MAX_SLOTS; i++) {
671 		struct siis_slot *slot = &ch->slot[i];
672 
673 		slot->dev = dev;
674 		slot->slot = i;
675 		slot->state = SIIS_SLOT_EMPTY;
676 		slot->ccb = NULL;
677 		callout_init_mtx(&slot->timeout, &ch->mtx, 0);
678 
679 		if (bus_dmamap_create(ch->dma.data_tag, 0, &slot->dma.data_map))
680 			device_printf(ch->dev, "FAILURE - create data_map\n");
681 	}
682 }
683 
684 static void
685 siis_slotsfree(device_t dev)
686 {
687 	struct siis_channel *ch = device_get_softc(dev);
688 	int i;
689 
690 	/* Free all dma slots */
691 	for (i = 0; i < SIIS_MAX_SLOTS; i++) {
692 		struct siis_slot *slot = &ch->slot[i];
693 
694 		callout_drain(&slot->timeout);
695 		if (slot->dma.data_map) {
696 			bus_dmamap_destroy(ch->dma.data_tag, slot->dma.data_map);
697 			slot->dma.data_map = NULL;
698 		}
699 	}
700 }
701 
702 static void
703 siis_notify_events(device_t dev)
704 {
705 	struct siis_channel *ch = device_get_softc(dev);
706 	struct cam_path *dpath;
707 	u_int32_t status;
708 	int i;
709 
710 	if (ch->quirks & SIIS_Q_SNTF) {
711 		status = ATA_INL(ch->r_mem, SIIS_P_SNTF);
712 		ATA_OUTL(ch->r_mem, SIIS_P_SNTF, status);
713 	} else {
714 		/*
715 		 * Without SNTF we have no idea which device sent notification.
716 		 * If PMP is connected, assume it, else - device.
717 		 */
718 		status = (ch->pm_present) ? 0x8000 : 0x0001;
719 	}
720 	if (bootverbose)
721 		device_printf(dev, "SNTF 0x%04x\n", status);
722 	for (i = 0; i < 16; i++) {
723 		if ((status & (1 << i)) == 0)
724 			continue;
725 		if (xpt_create_path(&dpath, NULL,
726 		    xpt_path_path_id(ch->path), i, 0) == CAM_REQ_CMP) {
727 			xpt_async(AC_SCSI_AEN, dpath, NULL);
728 			xpt_free_path(dpath);
729 		}
730 	}
731 
732 }
733 
734 static void
735 siis_phy_check_events(device_t dev)
736 {
737 	struct siis_channel *ch = device_get_softc(dev);
738 
739 	/* If we have a connection event, deal with it */
740 	if (ch->pm_level == 0) {
741 		u_int32_t status = ATA_INL(ch->r_mem, SIIS_P_SSTS);
742 		union ccb *ccb;
743 
744 		if (bootverbose) {
745 			if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
746 			    ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
747 			    ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) {
748 				device_printf(dev, "CONNECT requested\n");
749 			} else
750 				device_printf(dev, "DISCONNECT requested\n");
751 		}
752 		siis_reset(dev);
753 		if ((ccb = xpt_alloc_ccb_nowait()) == NULL)
754 			return;
755 		if (xpt_create_path(&ccb->ccb_h.path, NULL,
756 		    cam_sim_path(ch->sim),
757 		    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
758 			xpt_free_ccb(ccb);
759 			return;
760 		}
761 		xpt_rescan(ccb);
762 	}
763 }
764 
765 static void
766 siis_ch_intr_locked(void *data)
767 {
768 	device_t dev = (device_t)data;
769 	struct siis_channel *ch = device_get_softc(dev);
770 
771 	mtx_lock(&ch->mtx);
772 	siis_ch_intr(data);
773 	mtx_unlock(&ch->mtx);
774 }
775 
776 static void
777 siis_ch_intr(void *data)
778 {
779 	device_t dev = (device_t)data;
780 	struct siis_channel *ch = device_get_softc(dev);
781 	uint32_t istatus, sstatus, ctx, estatus, ok, err = 0;
782 	enum siis_err_type et;
783 	int i, ccs, port, tslots;
784 
785 	mtx_assert(&ch->mtx, MA_OWNED);
786 	/* Read command statuses. */
787 	sstatus = ATA_INL(ch->r_mem, SIIS_P_SS);
788 	ok = ch->rslots & ~sstatus;
789 	/* Complete all successfull commands. */
790 	for (i = 0; i < SIIS_MAX_SLOTS; i++) {
791 		if ((ok >> i) & 1)
792 			siis_end_transaction(&ch->slot[i], SIIS_ERR_NONE);
793 	}
794 	/* Do we have any other events? */
795 	if ((sstatus & SIIS_P_SS_ATTN) == 0)
796 		return;
797 	/* Read and clear interrupt statuses. */
798 	istatus = ATA_INL(ch->r_mem, SIIS_P_IS) &
799 	    (0xFFFF & ~SIIS_P_IX_COMMCOMP);
800 	ATA_OUTL(ch->r_mem, SIIS_P_IS, istatus);
801 	/* Process PHY events */
802 	if (istatus & SIIS_P_IX_PHYRDYCHG)
803 		siis_phy_check_events(dev);
804 	/* Process NOTIFY events */
805 	if (istatus & SIIS_P_IX_SDBN)
806 		siis_notify_events(dev);
807 	/* Process command errors */
808 	if (istatus & SIIS_P_IX_COMMERR) {
809 		estatus = ATA_INL(ch->r_mem, SIIS_P_CMDERR);
810 		ctx = ATA_INL(ch->r_mem, SIIS_P_CTX);
811 		ccs = (ctx & SIIS_P_CTX_SLOT) >> SIIS_P_CTX_SLOT_SHIFT;
812 		port = (ctx & SIIS_P_CTX_PMP) >> SIIS_P_CTX_PMP_SHIFT;
813 		err = ch->rslots & sstatus;
814 //device_printf(dev, "%s ERROR ss %08x is %08x rs %08x es %d act %d port %d serr %08x\n",
815 //    __func__, sstatus, istatus, ch->rslots, estatus, ccs, port,
816 //    ATA_INL(ch->r_mem, SIIS_P_SERR));
817 
818 		if (!ch->readlog && !ch->recovery) {
819 			xpt_freeze_simq(ch->sim, ch->numrslots);
820 			ch->recovery = 1;
821 		}
822 		if (ch->frozen) {
823 			union ccb *fccb = ch->frozen;
824 			ch->frozen = NULL;
825 			fccb->ccb_h.status &= ~CAM_STATUS_MASK;
826 			fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
827 			if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
828 				xpt_freeze_devq(fccb->ccb_h.path, 1);
829 				fccb->ccb_h.status |= CAM_DEV_QFRZN;
830 			}
831 			xpt_done(fccb);
832 		}
833 		if (estatus == SIIS_P_CMDERR_DEV ||
834 		    estatus == SIIS_P_CMDERR_SDB ||
835 		    estatus == SIIS_P_CMDERR_DATAFIS) {
836 			tslots = ch->numtslots[port];
837 			for (i = 0; i < SIIS_MAX_SLOTS; i++) {
838 				/* XXX: requests in loading state. */
839 				if (((ch->rslots >> i) & 1) == 0)
840 					continue;
841 				if (ch->slot[i].ccb->ccb_h.target_id != port)
842 					continue;
843 				if (tslots == 0) {
844 					/* Untagged operation. */
845 					if (i == ccs)
846 						et = SIIS_ERR_TFE;
847 					else
848 						et = SIIS_ERR_INNOCENT;
849 				} else {
850 					/* Tagged operation. */
851 					et = SIIS_ERR_NCQ;
852 				}
853 				siis_end_transaction(&ch->slot[i], et);
854 			}
855 			/*
856 			 * We can't reinit port if there are some other
857 			 * commands active, use resume to complete them.
858 			 */
859 			if (ch->rslots != 0)
860 				ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_RESUME);
861 		} else {
862 			if (estatus == SIIS_P_CMDERR_SENDFIS ||
863 			    estatus == SIIS_P_CMDERR_INCSTATE ||
864 			    estatus == SIIS_P_CMDERR_PPE ||
865 			    estatus == SIIS_P_CMDERR_SERVICE) {
866 				et = SIIS_ERR_SATA;
867 			} else
868 				et = SIIS_ERR_INVALID;
869 			for (i = 0; i < SIIS_MAX_SLOTS; i++) {
870 				/* XXX: requests in loading state. */
871 				if (((ch->rslots >> i) & 1) == 0)
872 					continue;
873 				siis_end_transaction(&ch->slot[i], et);
874 			}
875 		}
876 	}
877 }
878 
879 /* Must be called with channel locked. */
880 static int
881 siis_check_collision(device_t dev, union ccb *ccb)
882 {
883 	struct siis_channel *ch = device_get_softc(dev);
884 
885 	mtx_assert(&ch->mtx, MA_OWNED);
886 	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
887 	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
888 		/* Tagged command while we have no supported tag free. */
889 		if (((~ch->oslots) & (0x7fffffff >> (31 -
890 		    ch->curr[ccb->ccb_h.target_id].tags))) == 0)
891 			return (1);
892 	}
893 	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
894 	    (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) {
895 		/* Atomic command while anything active. */
896 		if (ch->numrslots != 0)
897 			return (1);
898 	}
899        /* We have some atomic command running. */
900        if (ch->aslots != 0)
901                return (1);
902 	return (0);
903 }
904 
905 /* Must be called with channel locked. */
906 static void
907 siis_begin_transaction(device_t dev, union ccb *ccb)
908 {
909 	struct siis_channel *ch = device_get_softc(dev);
910 	struct siis_slot *slot;
911 	int tag, tags;
912 
913 	mtx_assert(&ch->mtx, MA_OWNED);
914 	/* Choose empty slot. */
915 	tags = SIIS_MAX_SLOTS;
916 	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
917 	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA))
918 		tags = ch->curr[ccb->ccb_h.target_id].tags;
919 	tag = fls((~ch->oslots) & (0x7fffffff >> (31 - tags))) - 1;
920 	/* Occupy chosen slot. */
921 	slot = &ch->slot[tag];
922 	slot->ccb = ccb;
923 	/* Update channel stats. */
924 	ch->oslots |= (1 << slot->slot);
925 	ch->numrslots++;
926 	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
927 	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
928 		ch->numtslots[ccb->ccb_h.target_id]++;
929 	}
930 	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
931 	    (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT)))
932 		ch->aslots |= (1 << slot->slot);
933 	slot->dma.nsegs = 0;
934 	/* If request moves data, setup and load SG list */
935 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
936 		void *buf;
937 		bus_size_t size;
938 
939 		slot->state = SIIS_SLOT_LOADING;
940 		if (ccb->ccb_h.func_code == XPT_ATA_IO) {
941 			buf = ccb->ataio.data_ptr;
942 			size = ccb->ataio.dxfer_len;
943 		} else {
944 			buf = ccb->csio.data_ptr;
945 			size = ccb->csio.dxfer_len;
946 		}
947 		bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map,
948 		    buf, size, siis_dmasetprd, slot, 0);
949 	} else
950 		siis_execute_transaction(slot);
951 }
952 
953 /* Locked by busdma engine. */
954 static void
955 siis_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
956 {
957 	struct siis_slot *slot = arg;
958 	struct siis_channel *ch = device_get_softc(slot->dev);
959 	struct siis_cmd *ctp;
960 	struct siis_dma_prd *prd;
961 	int i;
962 
963 	mtx_assert(&ch->mtx, MA_OWNED);
964 	if (error) {
965 		device_printf(slot->dev, "DMA load error\n");
966 		if (!ch->readlog)
967 			xpt_freeze_simq(ch->sim, 1);
968 		siis_end_transaction(slot, SIIS_ERR_INVALID);
969 		return;
970 	}
971 	KASSERT(nsegs <= SIIS_SG_ENTRIES, ("too many DMA segment entries\n"));
972 	/* Get a piece of the workspace for this request */
973 	ctp = (struct siis_cmd *)
974 		(ch->dma.work + SIIS_CT_OFFSET + (SIIS_CT_SIZE * slot->slot));
975 	/* Fill S/G table */
976 	if (slot->ccb->ccb_h.func_code == XPT_ATA_IO)
977 		prd = &ctp->u.ata.prd[0];
978 	else
979 		prd = &ctp->u.atapi.prd[0];
980 	for (i = 0; i < nsegs; i++) {
981 		prd[i].dba = htole64(segs[i].ds_addr);
982 		prd[i].dbc = htole32(segs[i].ds_len);
983 		prd[i].control = 0;
984 	}
985 	prd[nsegs - 1].control = htole32(SIIS_PRD_TRM);
986 	slot->dma.nsegs = nsegs;
987 	bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map,
988 	    ((slot->ccb->ccb_h.flags & CAM_DIR_IN) ?
989 	    BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
990 	siis_execute_transaction(slot);
991 }
992 
993 /* Must be called with channel locked. */
994 static void
995 siis_execute_transaction(struct siis_slot *slot)
996 {
997 	device_t dev = slot->dev;
998 	struct siis_channel *ch = device_get_softc(dev);
999 	struct siis_cmd *ctp;
1000 	union ccb *ccb = slot->ccb;
1001 	u_int64_t prb_bus;
1002 
1003 	mtx_assert(&ch->mtx, MA_OWNED);
1004 	/* Get a piece of the workspace for this request */
1005 	ctp = (struct siis_cmd *)
1006 		(ch->dma.work + SIIS_CT_OFFSET + (SIIS_CT_SIZE * slot->slot));
1007 	ctp->control = 0;
1008 	ctp->protocol_override = 0;
1009 	ctp->transfer_count = 0;
1010 	/* Special handling for Soft Reset command. */
1011 	if (ccb->ccb_h.func_code == XPT_ATA_IO) {
1012 		if (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) {
1013 			ctp->control |= htole16(SIIS_PRB_SOFT_RESET);
1014 		} else {
1015 			ctp->control |= htole16(SIIS_PRB_PROTOCOL_OVERRIDE);
1016 			if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) {
1017 				ctp->protocol_override |=
1018 				    htole16(SIIS_PRB_PROTO_NCQ);
1019 			}
1020 			if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1021 				ctp->protocol_override |=
1022 				    htole16(SIIS_PRB_PROTO_READ);
1023 			} else
1024 			if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
1025 				ctp->protocol_override |=
1026 				    htole16(SIIS_PRB_PROTO_WRITE);
1027 			}
1028 		}
1029 	} else if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
1030 		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
1031 			ctp->control |= htole16(SIIS_PRB_PACKET_READ);
1032 		else
1033 		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1034 			ctp->control |= htole16(SIIS_PRB_PACKET_WRITE);
1035 	}
1036 	/* Special handling for Soft Reset command. */
1037 	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1038 	    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
1039 	    (ccb->ataio.cmd.control & ATA_A_RESET)) {
1040 		/* Kick controller into sane state */
1041 		siis_portinit(dev);
1042 	}
1043 	/* Setup the FIS for this request */
1044 	if (!siis_setup_fis(dev, ctp, ccb, slot->slot)) {
1045 		device_printf(ch->dev, "Setting up SATA FIS failed\n");
1046 		if (!ch->readlog)
1047 			xpt_freeze_simq(ch->sim, 1);
1048 		siis_end_transaction(slot, SIIS_ERR_INVALID);
1049 		return;
1050 	}
1051 	bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
1052 	    BUS_DMASYNC_PREWRITE);
1053 	/* Issue command to the controller. */
1054 	slot->state = SIIS_SLOT_RUNNING;
1055 	ch->rslots |= (1 << slot->slot);
1056 	prb_bus = ch->dma.work_bus +
1057 	      SIIS_CT_OFFSET + (SIIS_CT_SIZE * slot->slot);
1058 	ATA_OUTL(ch->r_mem, SIIS_P_CACTL(slot->slot), prb_bus);
1059 	ATA_OUTL(ch->r_mem, SIIS_P_CACTH(slot->slot), prb_bus >> 32);
1060 	/* Start command execution timeout */
1061 	callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 1000,
1062 	    (timeout_t*)siis_timeout, slot);
1063 	return;
1064 }
1065 
1066 /* Must be called with channel locked. */
1067 static void
1068 siis_process_timeout(device_t dev)
1069 {
1070 	struct siis_channel *ch = device_get_softc(dev);
1071 	int i;
1072 
1073 	mtx_assert(&ch->mtx, MA_OWNED);
1074 	if (!ch->readlog && !ch->recovery) {
1075 		xpt_freeze_simq(ch->sim, ch->numrslots);
1076 		ch->recovery = 1;
1077 	}
1078 	/* Handle the rest of commands. */
1079 	for (i = 0; i < SIIS_MAX_SLOTS; i++) {
1080 		/* Do we have a running request on slot? */
1081 		if (ch->slot[i].state < SIIS_SLOT_RUNNING)
1082 			continue;
1083 		siis_end_transaction(&ch->slot[i], SIIS_ERR_TIMEOUT);
1084 	}
1085 }
1086 
1087 /* Locked by callout mechanism. */
1088 static void
1089 siis_timeout(struct siis_slot *slot)
1090 {
1091 	device_t dev = slot->dev;
1092 	struct siis_channel *ch = device_get_softc(dev);
1093 
1094 	mtx_assert(&ch->mtx, MA_OWNED);
1095 	/* Check for stale timeout. */
1096 	if (slot->state < SIIS_SLOT_RUNNING)
1097 		return;
1098 	device_printf(dev, "Timeout on slot %d\n", slot->slot);
1099 	device_printf(dev, "%s is %08x ss %08x rs %08x es %08x sts %08x serr %08x\n",
1100 	    __func__, ATA_INL(ch->r_mem, SIIS_P_IS),
1101 	    ATA_INL(ch->r_mem, SIIS_P_SS), ch->rslots,
1102 	    ATA_INL(ch->r_mem, SIIS_P_CMDERR), ATA_INL(ch->r_mem, SIIS_P_STS),
1103 	    ATA_INL(ch->r_mem, SIIS_P_SERR));
1104 
1105 	if (ch->toslots == 0)
1106 		xpt_freeze_simq(ch->sim, 1);
1107 	ch->toslots |= (1 << slot->slot);
1108 	if ((ch->rslots & ~ch->toslots) == 0)
1109 		siis_process_timeout(dev);
1110 	else
1111 		device_printf(dev, " ... waiting for slots %08x\n",
1112 		    ch->rslots & ~ch->toslots);
1113 }
1114 
1115 /* Must be called with channel locked. */
1116 static void
1117 siis_end_transaction(struct siis_slot *slot, enum siis_err_type et)
1118 {
1119 	device_t dev = slot->dev;
1120 	struct siis_channel *ch = device_get_softc(dev);
1121 	union ccb *ccb = slot->ccb;
1122 
1123 	mtx_assert(&ch->mtx, MA_OWNED);
1124 	bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
1125 	    BUS_DMASYNC_POSTWRITE);
1126 	/* Read result registers to the result struct
1127 	 * May be incorrect if several commands finished same time,
1128 	 * so read only when sure or have to.
1129 	 */
1130 	if (ccb->ccb_h.func_code == XPT_ATA_IO) {
1131 		struct ata_res *res = &ccb->ataio.res;
1132 		if ((et == SIIS_ERR_TFE) ||
1133 		    (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT)) {
1134 			int offs = SIIS_P_LRAM_SLOT(slot->slot) + 8;
1135 
1136 			res->status = ATA_INB(ch->r_mem, offs + 2);
1137 			res->error = ATA_INB(ch->r_mem, offs + 3);
1138 			res->lba_low = ATA_INB(ch->r_mem, offs + 4);
1139 			res->lba_mid = ATA_INB(ch->r_mem, offs + 5);
1140 			res->lba_high = ATA_INB(ch->r_mem, offs + 6);
1141 			res->device = ATA_INB(ch->r_mem, offs + 7);
1142 			res->lba_low_exp = ATA_INB(ch->r_mem, offs + 8);
1143 			res->lba_mid_exp = ATA_INB(ch->r_mem, offs + 9);
1144 			res->lba_high_exp = ATA_INB(ch->r_mem, offs + 10);
1145 			res->sector_count = ATA_INB(ch->r_mem, offs + 12);
1146 			res->sector_count_exp = ATA_INB(ch->r_mem, offs + 13);
1147 		} else
1148 			bzero(res, sizeof(*res));
1149 	}
1150 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1151 		bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map,
1152 		    (ccb->ccb_h.flags & CAM_DIR_IN) ?
1153 		    BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1154 		bus_dmamap_unload(ch->dma.data_tag, slot->dma.data_map);
1155 	}
1156 	/* Set proper result status. */
1157 	if (et != SIIS_ERR_NONE || ch->recovery) {
1158 		ch->eslots |= (1 << slot->slot);
1159 		ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
1160 	}
1161 	/* In case of error, freeze device for proper recovery. */
1162 	if (et != SIIS_ERR_NONE &&
1163 	    !(ccb->ccb_h.status & CAM_DEV_QFRZN)) {
1164 		xpt_freeze_devq(ccb->ccb_h.path, 1);
1165 		ccb->ccb_h.status |= CAM_DEV_QFRZN;
1166 	}
1167 	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1168 	switch (et) {
1169 	case SIIS_ERR_NONE:
1170 		ccb->ccb_h.status |= CAM_REQ_CMP;
1171 		if (ccb->ccb_h.func_code == XPT_SCSI_IO)
1172 			ccb->csio.scsi_status = SCSI_STATUS_OK;
1173 		break;
1174 	case SIIS_ERR_INVALID:
1175 		ch->fatalerr = 1;
1176 		ccb->ccb_h.status |= CAM_REQ_INVALID;
1177 		break;
1178 	case SIIS_ERR_INNOCENT:
1179 		ccb->ccb_h.status |= CAM_REQUEUE_REQ;
1180 		break;
1181 	case SIIS_ERR_TFE:
1182 	case SIIS_ERR_NCQ:
1183 		if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
1184 			ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
1185 			ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1186 		} else {
1187 			ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR;
1188 		}
1189 		break;
1190 	case SIIS_ERR_SATA:
1191 		ch->fatalerr = 1;
1192 		ccb->ccb_h.status |= CAM_UNCOR_PARITY;
1193 		break;
1194 	case SIIS_ERR_TIMEOUT:
1195 		ch->fatalerr = 1;
1196 		ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
1197 		break;
1198 	default:
1199 		ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1200 	}
1201 	/* Free slot. */
1202 	ch->oslots &= ~(1 << slot->slot);
1203 	ch->rslots &= ~(1 << slot->slot);
1204 	ch->aslots &= ~(1 << slot->slot);
1205 	if (et != SIIS_ERR_TIMEOUT) {
1206 		if (ch->toslots == (1 << slot->slot))
1207 			xpt_release_simq(ch->sim, TRUE);
1208 		ch->toslots &= ~(1 << slot->slot);
1209 	}
1210 	slot->state = SIIS_SLOT_EMPTY;
1211 	slot->ccb = NULL;
1212 	/* Update channel stats. */
1213 	ch->numrslots--;
1214 	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1215 	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
1216 		ch->numtslots[ccb->ccb_h.target_id]--;
1217 	}
1218 	/* If it was our READ LOG command - process it. */
1219 	if (ch->readlog) {
1220 		siis_process_read_log(dev, ccb);
1221 	/* If it was NCQ command error, put result on hold. */
1222 	} else if (et == SIIS_ERR_NCQ) {
1223 		ch->hold[slot->slot] = ccb;
1224 		ch->numhslots++;
1225 	} else
1226 		xpt_done(ccb);
1227 	/* Unfreeze frozen command. */
1228 	if (ch->frozen && !siis_check_collision(dev, ch->frozen)) {
1229 		union ccb *fccb = ch->frozen;
1230 		ch->frozen = NULL;
1231 		siis_begin_transaction(dev, fccb);
1232 		xpt_release_simq(ch->sim, TRUE);
1233 	}
1234 	/* If we have no other active commands, ... */
1235 	if (ch->rslots == 0) {
1236 		/* if there were timeouts or fatal error - reset port. */
1237 		if (ch->toslots != 0 || ch->fatalerr) {
1238 			siis_reset(dev);
1239 		} else {
1240 			/* if we have slots in error, we can reinit port. */
1241 			if (ch->eslots != 0)
1242 				siis_portinit(dev);
1243 			/* if there commands on hold, we can do READ LOG. */
1244 			if (!ch->readlog && ch->numhslots)
1245 				siis_issue_read_log(dev);
1246 		}
1247 	/* If all the reset of commands are in timeout - abort them. */
1248 	} else if ((ch->rslots & ~ch->toslots) == 0)
1249 		siis_process_timeout(dev);
1250 }
1251 
1252 static void
1253 siis_issue_read_log(device_t dev)
1254 {
1255 	struct siis_channel *ch = device_get_softc(dev);
1256 	union ccb *ccb;
1257 	struct ccb_ataio *ataio;
1258 	int i;
1259 
1260 	/* Find some holden command. */
1261 	for (i = 0; i < SIIS_MAX_SLOTS; i++) {
1262 		if (ch->hold[i])
1263 			break;
1264 	}
1265 	if (i == SIIS_MAX_SLOTS)
1266 		return;
1267 	ch->readlog = 1;
1268 	ccb = xpt_alloc_ccb_nowait();
1269 	if (ccb == NULL) {
1270 		device_printf(dev, "Unable allocate READ LOG command");
1271 		return; /* XXX */
1272 	}
1273 	ccb->ccb_h = ch->hold[i]->ccb_h;	/* Reuse old header. */
1274 	ccb->ccb_h.func_code = XPT_ATA_IO;
1275 	ccb->ccb_h.flags = CAM_DIR_IN;
1276 	ccb->ccb_h.timeout = 1000;	/* 1s should be enough. */
1277 	ataio = &ccb->ataio;
1278 	ataio->data_ptr = malloc(512, M_SIIS, M_NOWAIT);
1279 	if (ataio->data_ptr == NULL) {
1280 		device_printf(dev, "Unable allocate memory for READ LOG command");
1281 		return; /* XXX */
1282 	}
1283 	ataio->dxfer_len = 512;
1284 	bzero(&ataio->cmd, sizeof(ataio->cmd));
1285 	ataio->cmd.flags = CAM_ATAIO_48BIT;
1286 	ataio->cmd.command = 0x2F;	/* READ LOG EXT */
1287 	ataio->cmd.sector_count = 1;
1288 	ataio->cmd.sector_count_exp = 0;
1289 	ataio->cmd.lba_low = 0x10;
1290 	ataio->cmd.lba_mid = 0;
1291 	ataio->cmd.lba_mid_exp = 0;
1292 	siis_begin_transaction(dev, ccb);
1293 }
1294 
1295 static void
1296 siis_process_read_log(device_t dev, union ccb *ccb)
1297 {
1298 	struct siis_channel *ch = device_get_softc(dev);
1299 	uint8_t *data;
1300 	struct ata_res *res;
1301 	int i;
1302 
1303 	ch->readlog = 0;
1304 	data = ccb->ataio.data_ptr;
1305 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
1306 	    (data[0] & 0x80) == 0) {
1307 		for (i = 0; i < SIIS_MAX_SLOTS; i++) {
1308 			if (!ch->hold[i])
1309 				continue;
1310 			if (ch->hold[i]->ccb_h.target_id != ccb->ccb_h.target_id)
1311 				continue;
1312 			if ((data[0] & 0x1F) == i) {
1313 				res = &ch->hold[i]->ataio.res;
1314 				res->status = data[2];
1315 				res->error = data[3];
1316 				res->lba_low = data[4];
1317 				res->lba_mid = data[5];
1318 				res->lba_high = data[6];
1319 				res->device = data[7];
1320 				res->lba_low_exp = data[8];
1321 				res->lba_mid_exp = data[9];
1322 				res->lba_high_exp = data[10];
1323 				res->sector_count = data[12];
1324 				res->sector_count_exp = data[13];
1325 			} else {
1326 				ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK;
1327 				ch->hold[i]->ccb_h.status |= CAM_REQUEUE_REQ;
1328 			}
1329 			xpt_done(ch->hold[i]);
1330 			ch->hold[i] = NULL;
1331 			ch->numhslots--;
1332 		}
1333 	} else {
1334 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
1335 			device_printf(dev, "Error while READ LOG EXT\n");
1336 		else if ((data[0] & 0x80) == 0) {
1337 			device_printf(dev, "Non-queued command error in READ LOG EXT\n");
1338 		}
1339 		for (i = 0; i < SIIS_MAX_SLOTS; i++) {
1340 			if (!ch->hold[i])
1341 				continue;
1342 			if (ch->hold[i]->ccb_h.target_id != ccb->ccb_h.target_id)
1343 				continue;
1344 			xpt_done(ch->hold[i]);
1345 			ch->hold[i] = NULL;
1346 			ch->numhslots--;
1347 		}
1348 	}
1349 	free(ccb->ataio.data_ptr, M_SIIS);
1350 	xpt_free_ccb(ccb);
1351 }
1352 
1353 static void
1354 siis_portinit(device_t dev)
1355 {
1356 	struct siis_channel *ch = device_get_softc(dev);
1357 	int i;
1358 
1359 	ch->eslots = 0;
1360 	ch->recovery = 0;
1361 	ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_RESUME);
1362 	for (i = 0; i < 16; i++) {
1363 		ATA_OUTL(ch->r_mem, SIIS_P_PMPSTS(i), 0),
1364 		ATA_OUTL(ch->r_mem, SIIS_P_PMPQACT(i), 0);
1365 	}
1366 	ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PORT_INIT);
1367 	siis_wait_ready(dev, 1000);
1368 }
1369 
1370 static int
1371 siis_devreset(device_t dev)
1372 {
1373 	struct siis_channel *ch = device_get_softc(dev);
1374 	int timeout = 0;
1375 	uint32_t val;
1376 
1377 	ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_DEV_RESET);
1378 	while (((val = ATA_INL(ch->r_mem, SIIS_P_STS)) &
1379 	    SIIS_P_CTL_DEV_RESET) != 0) {
1380 		DELAY(1000);
1381 		if (timeout++ > 100) {
1382 			device_printf(dev, "device reset stuck (timeout %dms) "
1383 			    "status = %08x\n", timeout, val);
1384 			return (EBUSY);
1385 		}
1386 	}
1387 	return (0);
1388 }
1389 
1390 static int
1391 siis_wait_ready(device_t dev, int t)
1392 {
1393 	struct siis_channel *ch = device_get_softc(dev);
1394 	int timeout = 0;
1395 	uint32_t val;
1396 
1397 	while (((val = ATA_INL(ch->r_mem, SIIS_P_STS)) &
1398 	    SIIS_P_CTL_READY) == 0) {
1399 		DELAY(1000);
1400 		if (timeout++ > t) {
1401 			device_printf(dev, "port is not ready (timeout %dms) "
1402 			    "status = %08x\n", t, val);
1403 			return (EBUSY);
1404 		}
1405 	}
1406 	return (0);
1407 }
1408 
1409 static void
1410 siis_reset(device_t dev)
1411 {
1412 	struct siis_channel *ch = device_get_softc(dev);
1413 	int i, retry = 0, sata_rev;
1414 	uint32_t val;
1415 
1416 	xpt_freeze_simq(ch->sim, 1);
1417 	if (bootverbose)
1418 		device_printf(dev, "SIIS reset...\n");
1419 	if (!ch->readlog && !ch->recovery)
1420 		xpt_freeze_simq(ch->sim, ch->numrslots);
1421 	/* Requeue frozen command. */
1422 	if (ch->frozen) {
1423 		union ccb *fccb = ch->frozen;
1424 		ch->frozen = NULL;
1425 		fccb->ccb_h.status &= ~CAM_STATUS_MASK;
1426 		fccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
1427 		if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
1428 			xpt_freeze_devq(fccb->ccb_h.path, 1);
1429 			fccb->ccb_h.status |= CAM_DEV_QFRZN;
1430 		}
1431 		xpt_done(fccb);
1432 	}
1433 	/* Requeue all running commands. */
1434 	for (i = 0; i < SIIS_MAX_SLOTS; i++) {
1435 		/* Do we have a running request on slot? */
1436 		if (ch->slot[i].state < SIIS_SLOT_RUNNING)
1437 			continue;
1438 		/* XXX; Commands in loading state. */
1439 		siis_end_transaction(&ch->slot[i], SIIS_ERR_INNOCENT);
1440 	}
1441 	/* Finish all holden commands as-is. */
1442 	for (i = 0; i < SIIS_MAX_SLOTS; i++) {
1443 		if (!ch->hold[i])
1444 			continue;
1445 		xpt_done(ch->hold[i]);
1446 		ch->hold[i] = NULL;
1447 		ch->numhslots--;
1448 	}
1449 	if (ch->toslots != 0)
1450 		xpt_release_simq(ch->sim, TRUE);
1451 	ch->eslots = 0;
1452 	ch->recovery = 0;
1453 	ch->toslots = 0;
1454 	ch->fatalerr = 0;
1455 	/* Disable port interrupts */
1456 	ATA_OUTL(ch->r_mem, SIIS_P_IECLR, 0x0000FFFF);
1457 	/* Set speed limit. */
1458 	sata_rev = ch->user[ch->pm_present ? 15 : 0].revision;
1459 	if (sata_rev == 1)
1460 		val = ATA_SC_SPD_SPEED_GEN1;
1461 	else if (sata_rev == 2)
1462 		val = ATA_SC_SPD_SPEED_GEN2;
1463 	else if (sata_rev == 3)
1464 		val = ATA_SC_SPD_SPEED_GEN3;
1465 	else
1466 		val = 0;
1467 	ATA_OUTL(ch->r_mem, SIIS_P_SCTL,
1468 	    ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 :
1469 	    (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)));
1470 retry:
1471 	siis_devreset(dev);
1472 	/* Reset and reconnect PHY, */
1473 	if (!siis_sata_connect(ch)) {
1474 		ch->devices = 0;
1475 		/* Enable port interrupts */
1476 		ATA_OUTL(ch->r_mem, SIIS_P_IESET, SIIS_P_IX_ENABLED);
1477 		if (bootverbose)
1478 			device_printf(dev,
1479 			    "SIIS reset done: phy reset found no device\n");
1480 		/* Tell the XPT about the event */
1481 		xpt_async(AC_BUS_RESET, ch->path, NULL);
1482 		xpt_release_simq(ch->sim, TRUE);
1483 		return;
1484 	}
1485 	/* Wait for clearing busy status. */
1486 	if (siis_wait_ready(dev, 10000)) {
1487 		device_printf(dev, "device ready timeout\n");
1488 		if (!retry) {
1489 			device_printf(dev, "trying full port reset ...\n");
1490 			/* Get port to the reset state. */
1491 			ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PORT_RESET);
1492 			DELAY(10000);
1493 			/* Get port out of reset state. */
1494 			ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PORT_RESET);
1495 			ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_32BIT);
1496 			if (ch->pm_present)
1497 				ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME);
1498 			else
1499 				ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME);
1500 			siis_wait_ready(dev, 5000);
1501 			retry = 1;
1502 			goto retry;
1503 		}
1504 	}
1505 	ch->devices = 1;
1506 	/* Enable port interrupts */
1507 	ATA_OUTL(ch->r_mem, SIIS_P_IS, 0xFFFFFFFF);
1508 	ATA_OUTL(ch->r_mem, SIIS_P_IESET, SIIS_P_IX_ENABLED);
1509 	if (bootverbose)
1510 		device_printf(dev, "SIIS reset done: devices=%08x\n", ch->devices);
1511 	/* Tell the XPT about the event */
1512 	xpt_async(AC_BUS_RESET, ch->path, NULL);
1513 	xpt_release_simq(ch->sim, TRUE);
1514 }
1515 
1516 static int
1517 siis_setup_fis(device_t dev, struct siis_cmd *ctp, union ccb *ccb, int tag)
1518 {
1519 	struct siis_channel *ch = device_get_softc(dev);
1520 	u_int8_t *fis = &ctp->fis[0];
1521 
1522 	bzero(fis, 24);
1523 	fis[0] = 0x27;  		/* host to device */
1524 	fis[1] = (ccb->ccb_h.target_id & 0x0f);
1525 	if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
1526 		fis[1] |= 0x80;
1527 		fis[2] = ATA_PACKET_CMD;
1528 		if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE &&
1529 		    ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA)
1530 			fis[3] = ATA_F_DMA;
1531 		else {
1532 			fis[5] = ccb->csio.dxfer_len;
1533 		        fis[6] = ccb->csio.dxfer_len >> 8;
1534 		}
1535 		fis[7] = ATA_D_LBA;
1536 		fis[15] = ATA_A_4BIT;
1537 		bzero(ctp->u.atapi.ccb, 16);
1538 		bcopy((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
1539 		    ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes,
1540 		    ctp->u.atapi.ccb, ccb->csio.cdb_len);
1541 	} else if ((ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) == 0) {
1542 		fis[1] |= 0x80;
1543 		fis[2] = ccb->ataio.cmd.command;
1544 		fis[3] = ccb->ataio.cmd.features;
1545 		fis[4] = ccb->ataio.cmd.lba_low;
1546 		fis[5] = ccb->ataio.cmd.lba_mid;
1547 		fis[6] = ccb->ataio.cmd.lba_high;
1548 		fis[7] = ccb->ataio.cmd.device;
1549 		fis[8] = ccb->ataio.cmd.lba_low_exp;
1550 		fis[9] = ccb->ataio.cmd.lba_mid_exp;
1551 		fis[10] = ccb->ataio.cmd.lba_high_exp;
1552 		fis[11] = ccb->ataio.cmd.features_exp;
1553 		if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) {
1554 			fis[12] = tag << 3;
1555 			fis[13] = 0;
1556 		} else {
1557 			fis[12] = ccb->ataio.cmd.sector_count;
1558 			fis[13] = ccb->ataio.cmd.sector_count_exp;
1559 		}
1560 		fis[15] = ATA_A_4BIT;
1561 	} else {
1562 		/* Soft reset. */
1563 	}
1564 	return (20);
1565 }
1566 
1567 static int
1568 siis_sata_connect(struct siis_channel *ch)
1569 {
1570 	u_int32_t status;
1571 	int timeout;
1572 
1573 	/* Wait up to 100ms for "connect well" */
1574 	for (timeout = 0; timeout < 100 ; timeout++) {
1575 		status = ATA_INL(ch->r_mem, SIIS_P_SSTS);
1576 		if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
1577 		    ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
1578 		    ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE))
1579 			break;
1580 		DELAY(1000);
1581 	}
1582 	if (timeout >= 100) {
1583 		if (bootverbose) {
1584 			device_printf(ch->dev, "SATA connect timeout status=%08x\n",
1585 			    status);
1586 		}
1587 		return (0);
1588 	}
1589 	if (bootverbose) {
1590 		device_printf(ch->dev, "SATA connect time=%dms status=%08x\n",
1591 		    timeout, status);
1592 	}
1593 	/* Clear SATA error register */
1594 	ATA_OUTL(ch->r_mem, SIIS_P_SERR, 0xffffffff);
1595 	return (1);
1596 }
1597 
1598 static void
1599 siisaction(struct cam_sim *sim, union ccb *ccb)
1600 {
1601 	device_t dev;
1602 	struct siis_channel *ch;
1603 
1604 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("siisaction func_code=%x\n",
1605 	    ccb->ccb_h.func_code));
1606 
1607 	ch = (struct siis_channel *)cam_sim_softc(sim);
1608 	dev = ch->dev;
1609 	mtx_assert(&ch->mtx, MA_OWNED);
1610 	switch (ccb->ccb_h.func_code) {
1611 	/* Common cases first */
1612 	case XPT_ATA_IO:	/* Execute the requested I/O operation */
1613 	case XPT_SCSI_IO:
1614 		if (ch->devices == 0) {
1615 			ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1616 			xpt_done(ccb);
1617 			break;
1618 		}
1619 		/* Check for command collision. */
1620 		if (siis_check_collision(dev, ccb)) {
1621 			/* Freeze command. */
1622 			ch->frozen = ccb;
1623 			/* We have only one frozen slot, so freeze simq also. */
1624 			xpt_freeze_simq(ch->sim, 1);
1625 			return;
1626 		}
1627 		siis_begin_transaction(dev, ccb);
1628 		break;
1629 	case XPT_EN_LUN:		/* Enable LUN as a target */
1630 	case XPT_TARGET_IO:		/* Execute target I/O request */
1631 	case XPT_ACCEPT_TARGET_IO:	/* Accept Host Target Mode CDB */
1632 	case XPT_CONT_TARGET_IO:	/* Continue Host Target I/O Connection*/
1633 	case XPT_ABORT:			/* Abort the specified CCB */
1634 		/* XXX Implement */
1635 		ccb->ccb_h.status = CAM_REQ_INVALID;
1636 		xpt_done(ccb);
1637 		break;
1638 	case XPT_SET_TRAN_SETTINGS:
1639 	{
1640 		struct	ccb_trans_settings *cts = &ccb->cts;
1641 		struct	siis_device *d;
1642 
1643 		if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
1644 			d = &ch->curr[ccb->ccb_h.target_id];
1645 		else
1646 			d = &ch->user[ccb->ccb_h.target_id];
1647 		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION)
1648 			d->revision = cts->xport_specific.sata.revision;
1649 		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE)
1650 			d->mode = cts->xport_specific.sata.mode;
1651 		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
1652 			d->bytecount = min(8192, cts->xport_specific.sata.bytecount);
1653 		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS)
1654 			d->tags = min(SIIS_MAX_SLOTS, cts->xport_specific.sata.tags);
1655 		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) {
1656 			ch->pm_present = cts->xport_specific.sata.pm_present;
1657 			if (ch->pm_present)
1658 				ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME);
1659 			else
1660 				ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME);
1661 		}
1662 		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS)
1663 			d->atapi = cts->xport_specific.sata.atapi;
1664 		ccb->ccb_h.status = CAM_REQ_CMP;
1665 		xpt_done(ccb);
1666 		break;
1667 	}
1668 	case XPT_GET_TRAN_SETTINGS:
1669 	/* Get default/user set transfer settings for the target */
1670 	{
1671 		struct	ccb_trans_settings *cts = &ccb->cts;
1672 		struct  siis_device *d;
1673 		uint32_t status;
1674 
1675 		if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
1676 			d = &ch->curr[ccb->ccb_h.target_id];
1677 		else
1678 			d = &ch->user[ccb->ccb_h.target_id];
1679 		cts->protocol = PROTO_ATA;
1680 		cts->protocol_version = PROTO_VERSION_UNSPECIFIED;
1681 		cts->transport = XPORT_SATA;
1682 		cts->transport_version = XPORT_VERSION_UNSPECIFIED;
1683 		cts->proto_specific.valid = 0;
1684 		cts->xport_specific.sata.valid = 0;
1685 		if (cts->type == CTS_TYPE_CURRENT_SETTINGS &&
1686 		    (ccb->ccb_h.target_id == 15 ||
1687 		    (ccb->ccb_h.target_id == 0 && !ch->pm_present))) {
1688 			status = ATA_INL(ch->r_mem, SIIS_P_SSTS) & ATA_SS_SPD_MASK;
1689 			if (status & 0x0f0) {
1690 				cts->xport_specific.sata.revision =
1691 				    (status & 0x0f0) >> 4;
1692 				cts->xport_specific.sata.valid |=
1693 				    CTS_SATA_VALID_REVISION;
1694 			}
1695 		} else {
1696 			cts->xport_specific.sata.revision = d->revision;
1697 			cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION;
1698 		}
1699 		cts->xport_specific.sata.mode = d->mode;
1700 		cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE;
1701 		cts->xport_specific.sata.bytecount = d->bytecount;
1702 		cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT;
1703 		cts->xport_specific.sata.pm_present = ch->pm_present;
1704 		cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM;
1705 		cts->xport_specific.sata.tags = d->tags;
1706 		cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS;
1707 		cts->xport_specific.sata.atapi = d->atapi;
1708 		cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI;
1709 		ccb->ccb_h.status = CAM_REQ_CMP;
1710 		xpt_done(ccb);
1711 		break;
1712 	}
1713 #if 0
1714 	case XPT_CALC_GEOMETRY:
1715 	{
1716 		struct	  ccb_calc_geometry *ccg;
1717 		uint32_t size_mb;
1718 		uint32_t secs_per_cylinder;
1719 
1720 		ccg = &ccb->ccg;
1721 		size_mb = ccg->volume_size
1722 			/ ((1024L * 1024L) / ccg->block_size);
1723 		if (size_mb >= 1024 && (aha->extended_trans != 0)) {
1724 			if (size_mb >= 2048) {
1725 				ccg->heads = 255;
1726 				ccg->secs_per_track = 63;
1727 			} else {
1728 				ccg->heads = 128;
1729 				ccg->secs_per_track = 32;
1730 			}
1731 		} else {
1732 			ccg->heads = 64;
1733 			ccg->secs_per_track = 32;
1734 		}
1735 		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
1736 		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
1737 		ccb->ccb_h.status = CAM_REQ_CMP;
1738 		xpt_done(ccb);
1739 		break;
1740 	}
1741 #endif
1742 	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
1743 	case XPT_RESET_DEV:	/* Bus Device Reset the specified SCSI device */
1744 		siis_reset(dev);
1745 		ccb->ccb_h.status = CAM_REQ_CMP;
1746 		xpt_done(ccb);
1747 		break;
1748 	case XPT_TERM_IO:		/* Terminate the I/O process */
1749 		/* XXX Implement */
1750 		ccb->ccb_h.status = CAM_REQ_INVALID;
1751 		xpt_done(ccb);
1752 		break;
1753 	case XPT_PATH_INQ:		/* Path routing inquiry */
1754 	{
1755 		struct ccb_pathinq *cpi = &ccb->cpi;
1756 
1757 		cpi->version_num = 1; /* XXX??? */
1758 		cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
1759 		cpi->hba_inquiry |= PI_SATAPM;
1760 		cpi->target_sprt = 0;
1761 		cpi->hba_misc = PIM_SEQSCAN;
1762 		cpi->hba_eng_cnt = 0;
1763 		cpi->max_target = 15;
1764 		cpi->max_lun = 0;
1765 		cpi->initiator_id = 0;
1766 		cpi->bus_id = cam_sim_bus(sim);
1767 		cpi->base_transfer_speed = 150000;
1768 		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1769 		strncpy(cpi->hba_vid, "SIIS", HBA_IDLEN);
1770 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1771 		cpi->unit_number = cam_sim_unit(sim);
1772 		cpi->transport = XPORT_SATA;
1773 		cpi->transport_version = XPORT_VERSION_UNSPECIFIED;
1774 		cpi->protocol = PROTO_ATA;
1775 		cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
1776 		cpi->ccb_h.status = CAM_REQ_CMP;
1777 		cpi->maxio = MAXPHYS;
1778 		xpt_done(ccb);
1779 		break;
1780 	}
1781 	default:
1782 		ccb->ccb_h.status = CAM_REQ_INVALID;
1783 		xpt_done(ccb);
1784 		break;
1785 	}
1786 }
1787 
1788 static void
1789 siispoll(struct cam_sim *sim)
1790 {
1791 	struct siis_channel *ch = (struct siis_channel *)cam_sim_softc(sim);
1792 
1793 	siis_ch_intr(ch->dev);
1794 }
1795