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