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