1183724Ssos/*-
2230132Suqs * Copyright (c) 1998 - 2008 S��ren Schmidt <sos@FreeBSD.org>
3183724Ssos * All rights reserved.
4183724Ssos *
5183724Ssos * Redistribution and use in source and binary forms, with or without
6183724Ssos * modification, are permitted provided that the following conditions
7183724Ssos * are met:
8183724Ssos * 1. Redistributions of source code must retain the above copyright
9183724Ssos *    notice, this list of conditions and the following disclaimer,
10183724Ssos *    without modification, immediately at the beginning of the file.
11183724Ssos * 2. Redistributions in binary form must reproduce the above copyright
12183724Ssos *    notice, this list of conditions and the following disclaimer in the
13183724Ssos *    documentation and/or other materials provided with the distribution.
14183724Ssos *
15183724Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16183724Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17183724Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18183724Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19183724Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20183724Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21183724Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22183724Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23183724Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24183724Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25183724Ssos */
26183724Ssos
27183724Ssos#include <sys/cdefs.h>
28183724Ssos__FBSDID("$FreeBSD$");
29183724Ssos
30183724Ssos#include <sys/param.h>
31183724Ssos#include <sys/module.h>
32183724Ssos#include <sys/systm.h>
33183724Ssos#include <sys/kernel.h>
34183724Ssos#include <sys/ata.h>
35183724Ssos#include <sys/bus.h>
36183724Ssos#include <sys/endian.h>
37183724Ssos#include <sys/malloc.h>
38183724Ssos#include <sys/lock.h>
39183724Ssos#include <sys/mutex.h>
40183724Ssos#include <sys/sema.h>
41183724Ssos#include <sys/taskqueue.h>
42183724Ssos#include <vm/uma.h>
43183724Ssos#include <machine/stdarg.h>
44183724Ssos#include <machine/resource.h>
45183724Ssos#include <machine/bus.h>
46183724Ssos#include <sys/rman.h>
47183724Ssos#include <dev/pci/pcivar.h>
48183724Ssos#include <dev/pci/pcireg.h>
49183724Ssos#include <dev/ata/ata-all.h>
50183724Ssos#include <dev/ata/ata-pci.h>
51183724Ssos#include <ata_if.h>
52183724Ssos
53183724Ssos/* local prototypes */
54183724Ssosstatic int ata_promise_chipinit(device_t dev);
55188765Smavstatic int ata_promise_ch_attach(device_t dev);
56183724Ssosstatic int ata_promise_status(device_t dev);
57183724Ssosstatic int ata_promise_dmastart(struct ata_request *request);
58183724Ssosstatic int ata_promise_dmastop(struct ata_request *request);
59183724Ssosstatic void ata_promise_dmareset(device_t dev);
60200171Smavstatic int ata_promise_setmode(device_t dev, int target, int mode);
61188765Smavstatic int ata_promise_tx2_ch_attach(device_t dev);
62183724Ssosstatic int ata_promise_tx2_status(device_t dev);
63188765Smavstatic int ata_promise_mio_ch_attach(device_t dev);
64188769Smavstatic int ata_promise_mio_ch_detach(device_t dev);
65183724Ssosstatic void ata_promise_mio_intr(void *data);
66183724Ssosstatic int ata_promise_mio_status(device_t dev);
67183724Ssosstatic int ata_promise_mio_command(struct ata_request *request);
68183724Ssosstatic void ata_promise_mio_reset(device_t dev);
69183724Ssosstatic int ata_promise_mio_pm_read(device_t dev, int port, int reg, u_int32_t *result);
70183724Ssosstatic int ata_promise_mio_pm_write(device_t dev, int port, int reg, u_int32_t result);
71183724Ssosstatic u_int32_t ata_promise_mio_softreset(device_t dev, int port);
72183724Ssosstatic void ata_promise_mio_dmainit(device_t dev);
73183724Ssosstatic void ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
74200171Smavstatic int ata_promise_mio_setmode(device_t dev, int target, int mode);
75203034Smavstatic int ata_promise_mio_getrev(device_t dev, int target);
76183724Ssosstatic void ata_promise_sx4_intr(void *data);
77183724Ssosstatic int ata_promise_sx4_command(struct ata_request *request);
78183724Ssosstatic int ata_promise_apkt(u_int8_t *bytep, struct ata_request *request);
79183724Ssosstatic void ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt);
80183724Ssosstatic void ata_promise_next_hpkt(struct ata_pci_controller *ctlr);
81183724Ssos
82183724Ssos/* misc defines */
83183724Ssos#define PR_OLD		0
84183724Ssos#define PR_NEW		1
85183724Ssos#define PR_TX		2
86183724Ssos#define PR_MIO		3
87183724Ssos#define PR_TX4		0x01
88183724Ssos#define PR_SX4X		0x02
89183724Ssos#define PR_SX6K		0x04
90183724Ssos#define PR_PATA		0x08
91183724Ssos#define PR_CMBO		0x10
92183724Ssos#define PR_CMBO2	0x20
93183724Ssos#define PR_SATA		0x40
94183724Ssos#define PR_SATA2	0x80
95183724Ssos
96183724Ssos/*
97183724Ssos * Promise chipset support functions
98183724Ssos */
99183724Ssos#define ATA_PDC_APKT_OFFSET     0x00000010
100183724Ssos#define ATA_PDC_HPKT_OFFSET     0x00000040
101183724Ssos#define ATA_PDC_ASG_OFFSET      0x00000080
102183724Ssos#define ATA_PDC_LSG_OFFSET      0x000000c0
103183724Ssos#define ATA_PDC_HSG_OFFSET      0x00000100
104183724Ssos#define ATA_PDC_CHN_OFFSET      0x00000400
105183724Ssos#define ATA_PDC_BUF_BASE        0x00400000
106183724Ssos#define ATA_PDC_BUF_OFFSET      0x00100000
107183724Ssos#define ATA_PDC_MAX_HPKT        8
108183724Ssos#define ATA_PDC_WRITE_REG       0x00
109183724Ssos#define ATA_PDC_WRITE_CTL       0x0e
110183724Ssos#define ATA_PDC_WRITE_END       0x08
111183724Ssos#define ATA_PDC_WAIT_NBUSY      0x10
112183724Ssos#define ATA_PDC_WAIT_READY      0x18
113183724Ssos#define ATA_PDC_1B              0x20
114183724Ssos#define ATA_PDC_2B              0x40
115183724Ssos
116183724Ssosstruct host_packet {
117183724Ssos    u_int32_t                   addr;
118183724Ssos    TAILQ_ENTRY(host_packet)    chain;
119183724Ssos};
120183724Ssos
121183724Ssosstruct ata_promise_sx4 {
122183724Ssos    struct mtx                  mtx;
123183724Ssos    TAILQ_HEAD(, host_packet)   queue;
124183724Ssos    int                         busy;
125183724Ssos};
126183724Ssos
127183724Ssosstatic int
128183724Ssosata_promise_probe(device_t dev)
129183724Ssos{
130183724Ssos    struct ata_pci_controller *ctlr = device_get_softc(dev);
131233282Smarius    const struct ata_chip_id *idx;
132242625Sdim    static const struct ata_chip_id ids[] =
133183724Ssos    {{ ATA_PDC20246,  0, PR_OLD, 0x00,     ATA_UDMA2, "PDC20246" },
134183724Ssos     { ATA_PDC20262,  0, PR_NEW, 0x00,     ATA_UDMA4, "PDC20262" },
135183724Ssos     { ATA_PDC20263,  0, PR_NEW, 0x00,     ATA_UDMA4, "PDC20263" },
136183724Ssos     { ATA_PDC20265,  0, PR_NEW, 0x00,     ATA_UDMA5, "PDC20265" },
137183724Ssos     { ATA_PDC20267,  0, PR_NEW, 0x00,     ATA_UDMA5, "PDC20267" },
138183724Ssos     { ATA_PDC20268,  0, PR_TX,  PR_TX4,   ATA_UDMA5, "PDC20268" },
139183724Ssos     { ATA_PDC20269,  0, PR_TX,  0x00,     ATA_UDMA6, "PDC20269" },
140183724Ssos     { ATA_PDC20270,  0, PR_TX,  PR_TX4,   ATA_UDMA5, "PDC20270" },
141183724Ssos     { ATA_PDC20271,  0, PR_TX,  0x00,     ATA_UDMA6, "PDC20271" },
142183724Ssos     { ATA_PDC20275,  0, PR_TX,  0x00,     ATA_UDMA6, "PDC20275" },
143183724Ssos     { ATA_PDC20276,  0, PR_TX,  PR_SX6K,  ATA_UDMA6, "PDC20276" },
144183724Ssos     { ATA_PDC20277,  0, PR_TX,  0x00,     ATA_UDMA6, "PDC20277" },
145183724Ssos     { ATA_PDC20318,  0, PR_MIO, PR_SATA,  ATA_SA150, "PDC20318" },
146183724Ssos     { ATA_PDC20319,  0, PR_MIO, PR_SATA,  ATA_SA150, "PDC20319" },
147183724Ssos     { ATA_PDC20371,  0, PR_MIO, PR_CMBO,  ATA_SA150, "PDC20371" },
148183724Ssos     { ATA_PDC20375,  0, PR_MIO, PR_CMBO,  ATA_SA150, "PDC20375" },
149183724Ssos     { ATA_PDC20376,  0, PR_MIO, PR_CMBO,  ATA_SA150, "PDC20376" },
150183724Ssos     { ATA_PDC20377,  0, PR_MIO, PR_CMBO,  ATA_SA150, "PDC20377" },
151183724Ssos     { ATA_PDC20378,  0, PR_MIO, PR_CMBO,  ATA_SA150, "PDC20378" },
152183724Ssos     { ATA_PDC20379,  0, PR_MIO, PR_CMBO,  ATA_SA150, "PDC20379" },
153183724Ssos     { ATA_PDC20571,  0, PR_MIO, PR_CMBO2, ATA_SA150, "PDC20571" },
154183724Ssos     { ATA_PDC20575,  0, PR_MIO, PR_CMBO2, ATA_SA150, "PDC20575" },
155183724Ssos     { ATA_PDC20579,  0, PR_MIO, PR_CMBO2, ATA_SA150, "PDC20579" },
156183724Ssos     { ATA_PDC20771,  0, PR_MIO, PR_CMBO2, ATA_SA300, "PDC20771" },
157183724Ssos     { ATA_PDC40775,  0, PR_MIO, PR_CMBO2, ATA_SA300, "PDC40775" },
158183724Ssos     { ATA_PDC20617,  0, PR_MIO, PR_PATA,  ATA_UDMA6, "PDC20617" },
159183724Ssos     { ATA_PDC20618,  0, PR_MIO, PR_PATA,  ATA_UDMA6, "PDC20618" },
160183724Ssos     { ATA_PDC20619,  0, PR_MIO, PR_PATA,  ATA_UDMA6, "PDC20619" },
161183724Ssos     { ATA_PDC20620,  0, PR_MIO, PR_PATA,  ATA_UDMA6, "PDC20620" },
162183724Ssos     { ATA_PDC20621,  0, PR_MIO, PR_SX4X,  ATA_UDMA5, "PDC20621" },
163183724Ssos     { ATA_PDC20622,  0, PR_MIO, PR_SX4X,  ATA_SA150, "PDC20622" },
164183724Ssos     { ATA_PDC40518,  0, PR_MIO, PR_SATA2, ATA_SA150, "PDC40518" },
165183724Ssos     { ATA_PDC40519,  0, PR_MIO, PR_SATA2, ATA_SA150, "PDC40519" },
166183724Ssos     { ATA_PDC40718,  0, PR_MIO, PR_SATA2, ATA_SA300, "PDC40718" },
167183724Ssos     { ATA_PDC40719,  0, PR_MIO, PR_SATA2, ATA_SA300, "PDC40719" },
168183724Ssos     { ATA_PDC40779,  0, PR_MIO, PR_SATA2, ATA_SA300, "PDC40779" },
169183724Ssos     { 0, 0, 0, 0, 0, 0}};
170183724Ssos    char buffer[64];
171183724Ssos    uintptr_t devid = 0;
172183724Ssos
173183724Ssos    if (pci_get_vendor(dev) != ATA_PROMISE_ID)
174183724Ssos	return ENXIO;
175183724Ssos
176183724Ssos    if (!(idx = ata_match_chip(dev, ids)))
177183724Ssos	return ENXIO;
178183724Ssos
179183724Ssos    /* if we are on a SuperTrak SX6000 dont attach */
180183724Ssos    if ((idx->cfg2 & PR_SX6K) && pci_get_class(GRANDPARENT(dev))==PCIC_BRIDGE &&
181183724Ssos	!BUS_READ_IVAR(device_get_parent(GRANDPARENT(dev)),
182183724Ssos		       GRANDPARENT(dev), PCI_IVAR_DEVID, &devid) &&
183183724Ssos	devid == ATA_I960RM)
184183724Ssos	return ENXIO;
185183724Ssos
186183724Ssos    strcpy(buffer, "Promise ");
187183724Ssos    strcat(buffer, idx->text);
188183724Ssos
189183724Ssos    /* if we are on a FastTrak TX4, adjust the interrupt resource */
190183724Ssos    if ((idx->cfg2 & PR_TX4) && pci_get_class(GRANDPARENT(dev))==PCIC_BRIDGE &&
191183724Ssos	!BUS_READ_IVAR(device_get_parent(GRANDPARENT(dev)),
192183724Ssos		       GRANDPARENT(dev), PCI_IVAR_DEVID, &devid) &&
193183724Ssos	((devid == ATA_DEC_21150) || (devid == ATA_DEC_21150_1))) {
194183724Ssos	static long start = 0, end = 0;
195183724Ssos
196183724Ssos	if (pci_get_slot(dev) == 1) {
197183724Ssos	    bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &end);
198183724Ssos	    strcat(buffer, " (channel 0+1)");
199183724Ssos	}
200183724Ssos	else if (pci_get_slot(dev) == 2 && start && end) {
201183724Ssos	    bus_set_resource(dev, SYS_RES_IRQ, 0, start, end);
202183724Ssos	    strcat(buffer, " (channel 2+3)");
203183724Ssos	}
204183724Ssos	else {
205183724Ssos	    start = end = 0;
206183724Ssos	}
207183724Ssos    }
208183724Ssos    sprintf(buffer, "%s %s controller", buffer, ata_mode2str(idx->max_dma));
209183724Ssos    device_set_desc_copy(dev, buffer);
210183724Ssos    ctlr->chip = idx;
211183724Ssos    ctlr->chipinit = ata_promise_chipinit;
212281140Smav    return (BUS_PROBE_LOW_PRIORITY);
213183724Ssos}
214183724Ssos
215183724Ssosstatic int
216183724Ssosata_promise_chipinit(device_t dev)
217183724Ssos{
218183724Ssos    struct ata_pci_controller *ctlr = device_get_softc(dev);
219203043Smav    int stat_reg;
220183724Ssos
221183724Ssos    if (ata_setup_interrupt(dev, ata_generic_intr))
222183724Ssos	return ENXIO;
223183724Ssos
224183724Ssos    switch  (ctlr->chip->cfg1) {
225183724Ssos    case PR_NEW:
226183724Ssos	/* setup clocks */
227183724Ssos	ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
228183724Ssos	/* FALLTHROUGH */
229183724Ssos
230183724Ssos    case PR_OLD:
231183724Ssos	/* enable burst mode */
232183724Ssos	ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
233188765Smav	ctlr->ch_attach = ata_promise_ch_attach;
234188769Smav	ctlr->ch_detach = ata_pci_ch_detach;
235183724Ssos	ctlr->setmode = ata_promise_setmode;
236183724Ssos	return 0;
237183724Ssos
238183724Ssos    case PR_TX:
239188765Smav	ctlr->ch_attach = ata_promise_tx2_ch_attach;
240188769Smav	ctlr->ch_detach = ata_pci_ch_detach;
241183724Ssos	ctlr->setmode = ata_promise_setmode;
242183724Ssos	return 0;
243183724Ssos
244183724Ssos    case PR_MIO:
245183724Ssos	ctlr->r_type1 = SYS_RES_MEMORY;
246183724Ssos	ctlr->r_rid1 = PCIR_BAR(4);
247183724Ssos	if (!(ctlr->r_res1 = bus_alloc_resource_any(dev, ctlr->r_type1,
248183724Ssos						    &ctlr->r_rid1, RF_ACTIVE)))
249183724Ssos	    goto failnfree;
250183724Ssos
251227000Smarius#ifdef __sparc64__
252227000Smarius	if (ctlr->chip->cfg2 == PR_SX4X &&
253227000Smarius	    !bus_space_map(rman_get_bustag(ctlr->r_res1),
254227000Smarius	    rman_get_bushandle(ctlr->r_res1), rman_get_size(ctlr->r_res1),
255227000Smarius	    BUS_SPACE_MAP_LINEAR, NULL))
256227000Smarius		goto failnfree;
257227000Smarius#endif
258227000Smarius
259183724Ssos	ctlr->r_type2 = SYS_RES_MEMORY;
260183724Ssos	ctlr->r_rid2 = PCIR_BAR(3);
261183724Ssos	if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
262183724Ssos						    &ctlr->r_rid2, RF_ACTIVE)))
263183724Ssos	    goto failnfree;
264183724Ssos
265183724Ssos	if (ctlr->chip->cfg2 == PR_SX4X) {
266183724Ssos	    struct ata_promise_sx4 *hpkt;
267183724Ssos	    u_int32_t dimm = ATA_INL(ctlr->r_res2, 0x000c0080);
268183724Ssos
269183724Ssos	    if (bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle) ||
270183724Ssos		bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS, NULL,
271183724Ssos			       ata_promise_sx4_intr, ctlr, &ctlr->handle)) {
272183724Ssos		device_printf(dev, "unable to setup interrupt\n");
273183724Ssos		goto failnfree;
274183724Ssos	    }
275183724Ssos
276183724Ssos	    /* print info about cache memory */
277183724Ssos	    device_printf(dev, "DIMM size %dMB @ 0x%08x%s\n",
278183724Ssos			  (((dimm >> 16) & 0xff)-((dimm >> 24) & 0xff)+1) << 4,
279183724Ssos			  ((dimm >> 24) & 0xff),
280183724Ssos			  ATA_INL(ctlr->r_res2, 0x000c0088) & (1<<16) ?
281183724Ssos			  " ECC enabled" : "" );
282183724Ssos
283183724Ssos	    /* adjust cache memory parameters */
284183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x000c000c,
285183724Ssos		     (ATA_INL(ctlr->r_res2, 0x000c000c) & 0xffff0000));
286183724Ssos
287183724Ssos	    /* setup host packet controls */
288183724Ssos	    hpkt = malloc(sizeof(struct ata_promise_sx4),
289224270Smav			  M_ATAPCI, M_NOWAIT | M_ZERO);
290253644Smav	    if (hpkt == NULL) {
291253644Smav		device_printf(dev, "Cannot allocate HPKT\n");
292253644Smav		goto failnfree;
293253644Smav	    }
294183724Ssos	    mtx_init(&hpkt->mtx, "ATA promise HPKT lock", NULL, MTX_DEF);
295183724Ssos	    TAILQ_INIT(&hpkt->queue);
296183724Ssos	    hpkt->busy = 0;
297192105Sjhb	    ctlr->chipset_data = hpkt;
298188765Smav	    ctlr->ch_attach = ata_promise_mio_ch_attach;
299188769Smav	    ctlr->ch_detach = ata_promise_mio_ch_detach;
300183724Ssos	    ctlr->reset = ata_promise_mio_reset;
301183724Ssos	    ctlr->setmode = ata_promise_setmode;
302183724Ssos	    ctlr->channels = 4;
303183724Ssos	    return 0;
304183724Ssos	}
305183724Ssos
306183724Ssos	/* mio type controllers need an interrupt intercept */
307183724Ssos	if (bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle) ||
308183724Ssos	    bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS, NULL,
309183724Ssos			       ata_promise_mio_intr, ctlr, &ctlr->handle)) {
310183724Ssos		device_printf(dev, "unable to setup interrupt\n");
311183724Ssos		goto failnfree;
312183724Ssos	}
313183724Ssos
314183724Ssos	switch (ctlr->chip->cfg2) {
315183724Ssos	case PR_PATA:
316183724Ssos	    ctlr->channels = ((ATA_INL(ctlr->r_res2, 0x48) & 0x01) > 0) +
317183724Ssos			     ((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 2;
318183724Ssos	    goto sata150;
319183724Ssos	case PR_CMBO:
320183724Ssos	    ctlr->channels = 3;
321183724Ssos	    goto sata150;
322183724Ssos	case PR_SATA:
323183724Ssos	    ctlr->channels = 4;
324183724Ssossata150:
325183724Ssos	    stat_reg = 0x6c;
326183724Ssos	    break;
327183724Ssos
328183724Ssos	case PR_CMBO2:
329183724Ssos	    ctlr->channels = 3;
330183724Ssos	    goto sataii;
331183724Ssos	case PR_SATA2:
332183724Ssos	default:
333183724Ssos	    ctlr->channels = 4;
334183724Ssossataii:
335183724Ssos	    stat_reg = 0x60;
336183724Ssos	    break;
337183724Ssos	}
338183724Ssos
339183724Ssos	/* prime fake interrupt register */
340203043Smav	ctlr->chipset_data = (void *)(uintptr_t)0xffffffff;
341183724Ssos
342183724Ssos	/* clear SATA status and unmask interrupts */
343183724Ssos	ATA_OUTL(ctlr->r_res2, stat_reg, 0x000000ff);
344183724Ssos
345183724Ssos	/* enable "long burst length" on gen2 chips */
346183724Ssos	if ((ctlr->chip->cfg2 == PR_SATA2) || (ctlr->chip->cfg2 == PR_CMBO2))
347183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x44, ATA_INL(ctlr->r_res2, 0x44) | 0x2000);
348183724Ssos
349188765Smav	ctlr->ch_attach = ata_promise_mio_ch_attach;
350188769Smav	ctlr->ch_detach = ata_promise_mio_ch_detach;
351183724Ssos	ctlr->reset = ata_promise_mio_reset;
352183724Ssos	ctlr->setmode = ata_promise_mio_setmode;
353203034Smav	ctlr->getrev = ata_promise_mio_getrev;
354183724Ssos
355183724Ssos	return 0;
356183724Ssos    }
357183724Ssos
358183724Ssosfailnfree:
359183724Ssos    if (ctlr->r_res2)
360183724Ssos	bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, ctlr->r_res2);
361183724Ssos    if (ctlr->r_res1)
362183724Ssos	bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1, ctlr->r_res1);
363183724Ssos    return ENXIO;
364183724Ssos}
365183724Ssos
366183724Ssosstatic int
367188765Smavata_promise_ch_attach(device_t dev)
368183724Ssos{
369188765Smav    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
370183724Ssos    struct ata_channel *ch = device_get_softc(dev);
371183724Ssos
372188765Smav    if (ata_pci_ch_attach(dev))
373183724Ssos	return ENXIO;
374183724Ssos
375188769Smav    if (ctlr->chip->cfg1 == PR_NEW) {
376188769Smav        ch->dma.start = ata_promise_dmastart;
377188769Smav        ch->dma.stop = ata_promise_dmastop;
378188769Smav        ch->dma.reset = ata_promise_dmareset;
379188769Smav    }
380188769Smav
381183724Ssos    ch->hw.status = ata_promise_status;
382200171Smav    ch->flags |= ATA_NO_ATAPI_DMA;
383200171Smav    ch->flags |= ATA_CHECKS_CABLE;
384183724Ssos    return 0;
385183724Ssos}
386183724Ssos
387183724Ssosstatic int
388183724Ssosata_promise_status(device_t dev)
389183724Ssos{
390183724Ssos    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
391183724Ssos    struct ata_channel *ch = device_get_softc(dev);
392183724Ssos
393183724Ssos    if (ATA_INL(ctlr->r_res1, 0x1c) & (ch->unit ? 0x00004000 : 0x00000400)) {
394183724Ssos	return ata_pci_status(dev);
395183724Ssos    }
396183724Ssos    return 0;
397183724Ssos}
398183724Ssos
399183724Ssosstatic int
400183724Ssosata_promise_dmastart(struct ata_request *request)
401183724Ssos{
402198717Smav    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
403183724Ssos    struct ata_channel *ch = device_get_softc(request->parent);
404183724Ssos
405198717Smav    if (request->flags & ATA_R_48BIT) {
406183724Ssos	ATA_OUTB(ctlr->r_res1, 0x11,
407183724Ssos		 ATA_INB(ctlr->r_res1, 0x11) | (ch->unit ? 0x08 : 0x02));
408183724Ssos	ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20,
409183724Ssos		 ((request->flags & ATA_R_READ) ? 0x05000000 : 0x06000000) |
410183724Ssos		 (request->bytecount >> 1));
411183724Ssos    }
412183724Ssos    ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, (ATA_IDX_INB(ch, ATA_BMSTAT_PORT) |
413183724Ssos		 (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
414183724Ssos    ATA_IDX_OUTL(ch, ATA_BMDTP_PORT, request->dma->sg_bus);
415183724Ssos    ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,
416183724Ssos		 ((request->flags & ATA_R_READ) ? ATA_BMCMD_WRITE_READ : 0) |
417183724Ssos		 ATA_BMCMD_START_STOP);
418183724Ssos    ch->dma.flags |= ATA_DMA_ACTIVE;
419183724Ssos    return 0;
420183724Ssos}
421183724Ssos
422183724Ssosstatic int
423183724Ssosata_promise_dmastop(struct ata_request *request)
424183724Ssos{
425198717Smav    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
426183724Ssos    struct ata_channel *ch = device_get_softc(request->parent);
427183724Ssos    int error;
428183724Ssos
429198717Smav    if (request->flags & ATA_R_48BIT) {
430183724Ssos	ATA_OUTB(ctlr->r_res1, 0x11,
431183724Ssos		 ATA_INB(ctlr->r_res1, 0x11) & ~(ch->unit ? 0x08 : 0x02));
432183724Ssos	ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20, 0);
433183724Ssos    }
434183724Ssos    error = ATA_IDX_INB(ch, ATA_BMSTAT_PORT);
435183724Ssos    ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,
436183724Ssos		 ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
437183724Ssos    ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);
438183724Ssos    ch->dma.flags &= ~ATA_DMA_ACTIVE;
439183724Ssos    return error;
440183724Ssos}
441183724Ssos
442183724Ssosstatic void
443183724Ssosata_promise_dmareset(device_t dev)
444183724Ssos{
445183724Ssos    struct ata_channel *ch = device_get_softc(dev);
446183724Ssos
447183724Ssos    ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,
448183724Ssos		 ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
449183724Ssos    ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);
450183724Ssos    ch->flags &= ~ATA_DMA_ACTIVE;
451183724Ssos}
452183724Ssos
453200171Smavstatic int
454200171Smavata_promise_setmode(device_t dev, int target, int mode)
455183724Ssos{
456200171Smav    device_t parent = device_get_parent(dev);
457200171Smav    struct ata_pci_controller *ctlr = device_get_softc(parent);
458200171Smav    struct ata_channel *ch = device_get_softc(dev);
459200171Smav    int devno = (ch->unit << 1) + target;
460233282Smarius    static const uint32_t timings[][2] = {
461183724Ssos    /*    PR_OLD      PR_NEW               mode */
462183724Ssos	{ 0x004ff329, 0x004fff2f },     /* PIO 0 */
463183724Ssos	{ 0x004fec25, 0x004ff82a },     /* PIO 1 */
464183724Ssos	{ 0x004fe823, 0x004ff026 },     /* PIO 2 */
465183724Ssos	{ 0x004fe622, 0x004fec24 },     /* PIO 3 */
466183724Ssos	{ 0x004fe421, 0x004fe822 },     /* PIO 4 */
467183724Ssos	{ 0x004567f3, 0x004acef6 },     /* MWDMA 0 */
468183724Ssos	{ 0x004467f3, 0x0048cef6 },     /* MWDMA 1 */
469183724Ssos	{ 0x004367f3, 0x0046cef6 },     /* MWDMA 2 */
470183724Ssos	{ 0x004367f3, 0x0046cef6 },     /* UDMA 0 */
471183724Ssos	{ 0x004247f3, 0x00448ef6 },     /* UDMA 1 */
472183724Ssos	{ 0x004127f3, 0x00436ef6 },     /* UDMA 2 */
473183724Ssos	{ 0,          0x00424ef6 },     /* UDMA 3 */
474183724Ssos	{ 0,          0x004127f3 },     /* UDMA 4 */
475183724Ssos	{ 0,          0x004127f3 }      /* UDMA 5 */
476183724Ssos    };
477183724Ssos
478200171Smav    mode = min(mode, ctlr->chip->max_dma);
479183724Ssos
480183724Ssos    switch (ctlr->chip->cfg1) {
481183724Ssos    case PR_OLD:
482183724Ssos    case PR_NEW:
483209872Smav	if (ata_dma_check_80pin && mode > ATA_UDMA2 &&
484209872Smav	    (pci_read_config(parent, 0x50, 2) &
485183724Ssos				 (ch->unit ? 1 << 11 : 1 << 10))) {
486183724Ssos	    ata_print_cable(dev, "controller");
487183724Ssos	    mode = ATA_UDMA2;
488183724Ssos	}
489183724Ssos	break;
490183724Ssos
491183724Ssos    case PR_TX:
492183724Ssos	ATA_IDX_OUTB(ch, ATA_BMDEVSPEC_0, 0x0b);
493209872Smav	if (ata_dma_check_80pin && mode > ATA_UDMA2 &&
494183724Ssos	    ATA_IDX_INB(ch, ATA_BMDEVSPEC_1) & 0x04) {
495183724Ssos	    ata_print_cable(dev, "controller");
496183724Ssos	    mode = ATA_UDMA2;
497183724Ssos	}
498183724Ssos	break;
499183724Ssos
500183724Ssos    case PR_MIO:
501209872Smav	if (ata_dma_check_80pin && mode > ATA_UDMA2 &&
502183724Ssos	    (ATA_INL(ctlr->r_res2,
503183724Ssos		     (ctlr->chip->cfg2 & PR_SX4X ? 0x000c0260 : 0x0260) +
504183724Ssos		     (ch->unit << 7)) & 0x01000000)) {
505183724Ssos	    ata_print_cable(dev, "controller");
506183724Ssos	    mode = ATA_UDMA2;
507183724Ssos	}
508183724Ssos	break;
509183724Ssos    }
510183724Ssos
511183724Ssos	if (ctlr->chip->cfg1 < PR_TX)
512200171Smav	    pci_write_config(parent, 0x60 + (devno << 2),
513183724Ssos			     timings[ata_mode2idx(mode)][ctlr->chip->cfg1], 4);
514200171Smav	return (mode);
515183724Ssos}
516183724Ssos
517183724Ssosstatic int
518188765Smavata_promise_tx2_ch_attach(device_t dev)
519183724Ssos{
520183724Ssos    struct ata_channel *ch = device_get_softc(dev);
521183724Ssos
522188765Smav    if (ata_pci_ch_attach(dev))
523183724Ssos	return ENXIO;
524183724Ssos
525183724Ssos    ch->hw.status = ata_promise_tx2_status;
526200171Smav    ch->flags |= ATA_CHECKS_CABLE;
527183724Ssos    return 0;
528183724Ssos}
529183724Ssos
530183724Ssosstatic int
531183724Ssosata_promise_tx2_status(device_t dev)
532183724Ssos{
533183724Ssos    struct ata_channel *ch = device_get_softc(dev);
534183724Ssos
535183724Ssos    ATA_IDX_OUTB(ch, ATA_BMDEVSPEC_0, 0x0b);
536183724Ssos    if (ATA_IDX_INB(ch, ATA_BMDEVSPEC_1) & 0x20) {
537183724Ssos	return ata_pci_status(dev);
538183724Ssos    }
539183724Ssos    return 0;
540183724Ssos}
541183724Ssos
542183724Ssosstatic int
543188765Smavata_promise_mio_ch_attach(device_t dev)
544183724Ssos{
545183724Ssos    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
546183724Ssos    struct ata_channel *ch = device_get_softc(dev);
547183724Ssos    int offset = (ctlr->chip->cfg2 & PR_SX4X) ? 0x000c0000 : 0;
548183724Ssos    int i;
549188765Smav
550188765Smav    ata_promise_mio_dmainit(dev);
551188765Smav
552183724Ssos    for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
553183724Ssos	ch->r_io[i].res = ctlr->r_res2;
554183724Ssos	ch->r_io[i].offset = offset + 0x0200 + (i << 2) + (ch->unit << 7);
555183724Ssos    }
556183724Ssos    ch->r_io[ATA_CONTROL].res = ctlr->r_res2;
557183724Ssos    ch->r_io[ATA_CONTROL].offset = offset + 0x0238 + (ch->unit << 7);
558183724Ssos    ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2;
559183724Ssos    ata_default_registers(dev);
560183724Ssos    if ((ctlr->chip->cfg2 & (PR_SATA | PR_SATA2)) ||
561183724Ssos	((ctlr->chip->cfg2 & (PR_CMBO | PR_CMBO2)) && ch->unit < 2)) {
562183724Ssos	ch->r_io[ATA_SSTATUS].res = ctlr->r_res2;
563183724Ssos	ch->r_io[ATA_SSTATUS].offset = 0x400 + (ch->unit << 8);
564183724Ssos	ch->r_io[ATA_SERROR].res = ctlr->r_res2;
565183724Ssos	ch->r_io[ATA_SERROR].offset = 0x404 + (ch->unit << 8);
566183724Ssos	ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
567183724Ssos	ch->r_io[ATA_SCONTROL].offset = 0x408 + (ch->unit << 8);
568183724Ssos	ch->flags |= ATA_NO_SLAVE;
569200171Smav	ch->flags |= ATA_SATA;
570183724Ssos    }
571183724Ssos    ch->flags |= ATA_USE_16BIT;
572200171Smav    ch->flags |= ATA_CHECKS_CABLE;
573183724Ssos
574183724Ssos    ata_generic_hw(dev);
575183724Ssos    if (ctlr->chip->cfg2 & PR_SX4X) {
576183724Ssos	ch->hw.command = ata_promise_sx4_command;
577183724Ssos    }
578183724Ssos    else {
579183724Ssos	ch->hw.command = ata_promise_mio_command;
580183724Ssos	ch->hw.status = ata_promise_mio_status;
581183724Ssos	ch->hw.softreset = ata_promise_mio_softreset;
582183724Ssos	ch->hw.pm_read = ata_promise_mio_pm_read;
583183724Ssos	ch->hw.pm_write = ata_promise_mio_pm_write;
584183724Ssos     }
585183724Ssos    return 0;
586183724Ssos}
587183724Ssos
588188769Smavstatic int
589188769Smavata_promise_mio_ch_detach(device_t dev)
590188769Smav{
591188769Smav
592188769Smav    ata_dmafini(dev);
593188769Smav    return (0);
594188769Smav}
595188769Smav
596183724Ssosstatic void
597183724Ssosata_promise_mio_intr(void *data)
598183724Ssos{
599183724Ssos    struct ata_pci_controller *ctlr = data;
600183724Ssos    struct ata_channel *ch;
601183724Ssos    u_int32_t vector;
602203043Smav    int unit;
603183724Ssos
604183724Ssos    /*
605183724Ssos     * since reading interrupt status register on early "mio" chips
606183724Ssos     * clears the status bits we cannot read it for each channel later on
607183724Ssos     * in the generic interrupt routine.
608183724Ssos     */
609183724Ssos    vector = ATA_INL(ctlr->r_res2, 0x040);
610183724Ssos    ATA_OUTL(ctlr->r_res2, 0x040, vector);
611203043Smav    ctlr->chipset_data = (void *)(uintptr_t)vector;
612183724Ssos
613183724Ssos    for (unit = 0; unit < ctlr->channels; unit++) {
614183724Ssos	if ((ch = ctlr->interrupt[unit].argument))
615183724Ssos	    ctlr->interrupt[unit].function(ch);
616183724Ssos    }
617183724Ssos
618203043Smav    ctlr->chipset_data = (void *)(uintptr_t)0xffffffff;
619183724Ssos}
620183724Ssos
621183724Ssosstatic int
622183724Ssosata_promise_mio_status(device_t dev)
623183724Ssos{
624183724Ssos    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
625183724Ssos    struct ata_channel *ch = device_get_softc(dev);
626203043Smav    u_int32_t stat_reg, vector, status;
627183724Ssos
628183724Ssos    switch (ctlr->chip->cfg2) {
629183724Ssos    case PR_PATA:
630183724Ssos    case PR_CMBO:
631183724Ssos    case PR_SATA:
632183724Ssos	stat_reg = 0x6c;
633183724Ssos	break;
634183724Ssos    case PR_CMBO2:
635183724Ssos    case PR_SATA2:
636183724Ssos    default:
637183724Ssos	stat_reg = 0x60;
638183724Ssos	break;
639183724Ssos    }
640183724Ssos
641183724Ssos    /* read and acknowledge interrupt */
642203058Smav    vector = (uint32_t)(uintptr_t)ctlr->chipset_data;
643183724Ssos
644183724Ssos    /* read and clear interface status */
645183724Ssos    status = ATA_INL(ctlr->r_res2, stat_reg);
646183724Ssos    ATA_OUTL(ctlr->r_res2, stat_reg, status & (0x00000011 << ch->unit));
647183724Ssos
648183724Ssos    /* check for and handle disconnect events */
649188903Smav    if (status & (0x00000001 << ch->unit)) {
650183724Ssos	if (bootverbose)
651183724Ssos	    device_printf(dev, "DISCONNECT requested\n");
652188903Smav	taskqueue_enqueue(taskqueue_thread, &ch->conntask);
653183724Ssos    }
654183724Ssos
655183724Ssos    /* check for and handle connect events */
656188903Smav    if (status & (0x00000010 << ch->unit)) {
657183724Ssos	if (bootverbose)
658183724Ssos	    device_printf(dev, "CONNECT requested\n");
659188903Smav	taskqueue_enqueue(taskqueue_thread, &ch->conntask);
660183724Ssos    }
661183724Ssos
662183724Ssos    /* do we have any device action ? */
663183724Ssos    return (vector & (1 << (ch->unit + 1)));
664183724Ssos}
665183724Ssos
666183724Ssosstatic int
667183724Ssosata_promise_mio_command(struct ata_request *request)
668183724Ssos{
669198717Smav    struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
670183724Ssos    struct ata_channel *ch = device_get_softc(request->parent);
671183724Ssos
672183724Ssos    u_int32_t *wordp = (u_int32_t *)ch->dma.work;
673183724Ssos
674183724Ssos    ATA_OUTL(ctlr->r_res2, (ch->unit + 1) << 2, 0x00000001);
675183724Ssos
676189295Smav    if ((ctlr->chip->cfg2 == PR_SATA2) ||
677189295Smav        ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) {
678189295Smav	/* set portmultiplier port */
679198717Smav	ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), request->unit & 0x0f);
680189295Smav    }
681183724Ssos
682183724Ssos    /* XXX SOS add ATAPI commands support later */
683183724Ssos    switch (request->u.ata.command) {
684183724Ssos    default:
685183724Ssos	return ata_generic_command(request);
686183724Ssos
687183724Ssos    case ATA_READ_DMA:
688183724Ssos    case ATA_READ_DMA48:
689183724Ssos	wordp[0] = htole32(0x04 | ((ch->unit + 1) << 16) | (0x00 << 24));
690183724Ssos	break;
691183724Ssos
692183724Ssos    case ATA_WRITE_DMA:
693183724Ssos    case ATA_WRITE_DMA48:
694183724Ssos	wordp[0] = htole32(0x00 | ((ch->unit + 1) << 16) | (0x00 << 24));
695183724Ssos	break;
696183724Ssos    }
697183724Ssos    wordp[1] = htole32(request->dma->sg_bus);
698183724Ssos    wordp[2] = 0;
699183724Ssos    ata_promise_apkt((u_int8_t*)wordp, request);
700183724Ssos
701183724Ssos    ATA_OUTL(ctlr->r_res2, 0x0240 + (ch->unit << 7), ch->dma.work_bus);
702183724Ssos    return 0;
703183724Ssos}
704183724Ssos
705183724Ssosstatic void
706183724Ssosata_promise_mio_reset(device_t dev)
707183724Ssos{
708183724Ssos    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
709183724Ssos    struct ata_channel *ch = device_get_softc(dev);
710183724Ssos    struct ata_promise_sx4 *hpktp;
711183724Ssos
712183724Ssos    switch (ctlr->chip->cfg2) {
713183724Ssos    case PR_SX4X:
714183724Ssos
715183724Ssos	/* softreset channel ATA module */
716192105Sjhb	hpktp = ctlr->chipset_data;
717183724Ssos	ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7), ch->unit + 1);
718183724Ssos	ata_udelay(1000);
719183724Ssos	ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7),
720183724Ssos		 (ATA_INL(ctlr->r_res2, 0xc0260 + (ch->unit << 7)) &
721183724Ssos		  ~0x00003f9f) | (ch->unit + 1));
722183724Ssos
723183724Ssos	/* softreset HOST module */ /* XXX SOS what about other outstandings */
724183724Ssos	mtx_lock(&hpktp->mtx);
725183724Ssos	ATA_OUTL(ctlr->r_res2, 0xc012c,
726183724Ssos		 (ATA_INL(ctlr->r_res2, 0xc012c) & ~0x00000f9f) | (1 << 11));
727183724Ssos	DELAY(10);
728183724Ssos	ATA_OUTL(ctlr->r_res2, 0xc012c,
729183724Ssos		 (ATA_INL(ctlr->r_res2, 0xc012c) & ~0x00000f9f));
730183724Ssos	hpktp->busy = 0;
731183724Ssos	mtx_unlock(&hpktp->mtx);
732183724Ssos	ata_generic_reset(dev);
733183724Ssos	break;
734183724Ssos
735183724Ssos    case PR_PATA:
736183724Ssos    case PR_CMBO:
737183724Ssos    case PR_SATA:
738183724Ssos	if ((ctlr->chip->cfg2 == PR_SATA) ||
739183724Ssos	    ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2))) {
740183724Ssos
741183724Ssos	    /* mask plug/unplug intr */
742183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x06c, (0x00110000 << ch->unit));
743183724Ssos	}
744183724Ssos
745183724Ssos	/* softreset channels ATA module */
746183724Ssos	ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), (1 << 11));
747183724Ssos	ata_udelay(10000);
748183724Ssos	ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7),
749183724Ssos		 (ATA_INL(ctlr->r_res2, 0x0260 + (ch->unit << 7)) &
750183724Ssos		  ~0x00003f9f) | (ch->unit + 1));
751183724Ssos
752183724Ssos	if ((ctlr->chip->cfg2 == PR_SATA) ||
753183724Ssos	    ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2))) {
754183724Ssos
755190581Smav	    if (ata_sata_phy_reset(dev, -1, 1))
756183724Ssos		ata_generic_reset(dev);
757209884Smav	    else
758209884Smav		ch->devices = 0;
759183724Ssos
760183724Ssos	    /* reset and enable plug/unplug intr */
761183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x06c, (0x00000011 << ch->unit));
762183724Ssos	}
763183724Ssos	else
764183724Ssos	    ata_generic_reset(dev);
765183724Ssos	break;
766183724Ssos
767183724Ssos    case PR_CMBO2:
768183724Ssos    case PR_SATA2:
769183724Ssos	if ((ctlr->chip->cfg2 == PR_SATA2) ||
770183724Ssos	    ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) {
771183724Ssos	    /* set portmultiplier port */
772183724Ssos	    //ATA_OUTL(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f);
773183724Ssos
774183724Ssos	    /* mask plug/unplug intr */
775183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x060, (0x00110000 << ch->unit));
776183724Ssos	}
777183724Ssos
778183724Ssos	/* softreset channels ATA module */
779183724Ssos	ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), (1 << 11));
780183724Ssos	ata_udelay(10000);
781183724Ssos	ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7),
782183724Ssos		 (ATA_INL(ctlr->r_res2, 0x0260 + (ch->unit << 7)) &
783183724Ssos		  ~0x00003f9f) | (ch->unit + 1));
784183724Ssos
785183724Ssos	if ((ctlr->chip->cfg2 == PR_SATA2) ||
786183724Ssos	    ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) {
787183724Ssos
788183724Ssos	    /* set PHY mode to "improved" */
789183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x414 + (ch->unit << 8),
790183724Ssos		     (ATA_INL(ctlr->r_res2, 0x414 + (ch->unit << 8)) &
791183724Ssos		     ~0x00000003) | 0x00000001);
792183724Ssos
793190581Smav	    if (ata_sata_phy_reset(dev, -1, 1)) {
794183724Ssos		u_int32_t signature = ch->hw.softreset(dev, ATA_PM);
795183724Ssos
796183724Ssos		if (1 | bootverbose)
797183724Ssos        	    device_printf(dev, "SIGNATURE: %08x\n", signature);
798183724Ssos
799188906Smav		switch (signature >> 16) {
800188906Smav		case 0x0000:
801183724Ssos		    ch->devices = ATA_ATA_MASTER;
802183724Ssos		    break;
803188906Smav		case 0x9669:
804183724Ssos		    ch->devices = ATA_PORTMULTIPLIER;
805183724Ssos		    ata_pm_identify(dev);
806183724Ssos		    break;
807188906Smav		case 0xeb14:
808183724Ssos		    ch->devices = ATA_ATAPI_MASTER;
809183724Ssos		    break;
810183724Ssos		default: /* SOS XXX */
811183724Ssos		    if (bootverbose)
812183724Ssos			device_printf(dev,
813188935Smav				      "No signature, assuming disk device\n");
814183724Ssos		    ch->devices = ATA_ATA_MASTER;
815183724Ssos		}
816183724Ssos		if (bootverbose)
817183724Ssos		    device_printf(dev, "promise_mio_reset devices=%08x\n",
818183724Ssos		    		  ch->devices);
819183724Ssos
820203033Smav	    } else
821203033Smav		ch->devices = 0;
822183724Ssos
823183724Ssos	    /* reset and enable plug/unplug intr */
824183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x060, (0x00000011 << ch->unit));
825183724Ssos
826183724Ssos	    ///* set portmultiplier port */
827183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x00);
828183724Ssos	}
829183724Ssos	else
830183724Ssos	    ata_generic_reset(dev);
831183724Ssos	break;
832183724Ssos
833183724Ssos    }
834183724Ssos}
835183724Ssos
836183724Ssosstatic int
837183724Ssosata_promise_mio_pm_read(device_t dev, int port, int reg, u_int32_t *result)
838183724Ssos{
839183724Ssos    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
840183724Ssos    struct ata_channel *ch = device_get_softc(dev);
841183724Ssos    int timeout = 0;
842183724Ssos
843214016Smav    if (port < 0) {
844214016Smav	*result = ATA_IDX_INL(ch, reg);
845214016Smav	return (0);
846214016Smav    }
847214016Smav    if (port < ATA_PM) {
848214016Smav	switch (reg) {
849214016Smav	case ATA_SSTATUS:
850214016Smav	    reg = 0;
851214016Smav	    break;
852214016Smav	case ATA_SERROR:
853214016Smav	    reg = 1;
854214016Smav	    break;
855214016Smav	case ATA_SCONTROL:
856214016Smav	    reg = 2;
857214016Smav	    break;
858214016Smav	default:
859214016Smav	    return (EINVAL);
860214016Smav	}
861214016Smav    }
862183724Ssos    /* set portmultiplier port */
863183724Ssos    ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f);
864183724Ssos
865183724Ssos    ATA_IDX_OUTB(ch, ATA_FEATURE, reg);
866183724Ssos    ATA_IDX_OUTB(ch, ATA_DRIVE, port);
867183724Ssos
868183724Ssos    ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_READ_PM);
869183724Ssos
870183724Ssos    while (timeout < 1000000) {
871183724Ssos	u_int8_t status = ATA_IDX_INB(ch, ATA_STATUS);
872183724Ssos	if (!(status & ATA_S_BUSY))
873183724Ssos	    break;
874183724Ssos	timeout += 1000;
875183724Ssos	DELAY(1000);
876183724Ssos    }
877183724Ssos    if (timeout >= 1000000)
878183724Ssos	return ATA_E_ABORT;
879183724Ssos
880183724Ssos    *result = ATA_IDX_INB(ch, ATA_COUNT) |
881183724Ssos	      (ATA_IDX_INB(ch, ATA_SECTOR) << 8) |
882183724Ssos	      (ATA_IDX_INB(ch, ATA_CYL_LSB) << 16) |
883183724Ssos	      (ATA_IDX_INB(ch, ATA_CYL_MSB) << 24);
884183724Ssos    return 0;
885183724Ssos}
886183724Ssos
887183724Ssosstatic int
888183724Ssosata_promise_mio_pm_write(device_t dev, int port, int reg, u_int32_t value)
889183724Ssos{
890183724Ssos    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
891183724Ssos    struct ata_channel *ch = device_get_softc(dev);
892183724Ssos    int timeout = 0;
893183724Ssos
894214016Smav    if (port < 0) {
895214016Smav	ATA_IDX_OUTL(ch, reg, value);
896214016Smav	return (0);
897214016Smav    }
898214016Smav    if (port < ATA_PM) {
899214016Smav	switch (reg) {
900214016Smav	case ATA_SSTATUS:
901214016Smav	    reg = 0;
902214016Smav	    break;
903214016Smav	case ATA_SERROR:
904214016Smav	    reg = 1;
905214016Smav	    break;
906214016Smav	case ATA_SCONTROL:
907214016Smav	    reg = 2;
908214016Smav	    break;
909214016Smav	default:
910214016Smav	    return (EINVAL);
911214016Smav	}
912214016Smav    }
913183724Ssos    /* set portmultiplier port */
914183724Ssos    ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f);
915183724Ssos
916183724Ssos    ATA_IDX_OUTB(ch, ATA_FEATURE, reg);
917183724Ssos    ATA_IDX_OUTB(ch, ATA_DRIVE, port);
918183724Ssos    ATA_IDX_OUTB(ch, ATA_COUNT, value & 0xff);
919183724Ssos    ATA_IDX_OUTB(ch, ATA_SECTOR, (value >> 8) & 0xff);
920183724Ssos    ATA_IDX_OUTB(ch, ATA_CYL_LSB, (value >> 16) & 0xff);
921183724Ssos    ATA_IDX_OUTB(ch, ATA_CYL_MSB, (value >> 24) & 0xff);
922183724Ssos
923183724Ssos    ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_WRITE_PM);
924183724Ssos
925183724Ssos    while (timeout < 1000000) {
926183724Ssos	u_int8_t status = ATA_IDX_INB(ch, ATA_STATUS);
927183724Ssos	if (!(status & ATA_S_BUSY))
928183724Ssos	    break;
929183724Ssos	timeout += 1000;
930183724Ssos	DELAY(1000);
931183724Ssos    }
932183724Ssos    if (timeout >= 1000000)
933183724Ssos	return ATA_E_ABORT;
934183724Ssos
935183724Ssos    return ATA_IDX_INB(ch, ATA_ERROR);
936183724Ssos}
937183724Ssos
938183724Ssos/* must be called with ATA channel locked and state_mtx held */
939183724Ssosstatic u_int32_t
940183724Ssosata_promise_mio_softreset(device_t dev, int port)
941183724Ssos{
942183724Ssos    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
943183724Ssos    struct ata_channel *ch = device_get_softc(dev);
944183724Ssos    int timeout;
945183724Ssos
946183724Ssos    /* set portmultiplier port */
947183724Ssos    ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), port & 0x0f);
948183724Ssos
949183724Ssos    /* softreset device on this channel */
950183724Ssos    ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(ATA_MASTER));
951183724Ssos    DELAY(10);
952183724Ssos    ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS | ATA_A_RESET);
953183724Ssos    ata_udelay(10000);
954183724Ssos    ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS);
955183724Ssos    ata_udelay(150000);
956183724Ssos    ATA_IDX_INB(ch, ATA_ERROR);
957183724Ssos
958183724Ssos    /* wait for BUSY to go inactive */
959183724Ssos    for (timeout = 0; timeout < 100; timeout++) {
960183724Ssos	u_int8_t err, stat;
961183724Ssos
962183724Ssos	err = ATA_IDX_INB(ch, ATA_ERROR);
963183724Ssos	stat = ATA_IDX_INB(ch, ATA_STATUS);
964183724Ssos
965183724Ssos	//if (stat == err && timeout > (stat & ATA_S_BUSY ? 100 : 10))
966183724Ssos	    //break;
967183724Ssos
968183724Ssos	if (!(stat & ATA_S_BUSY)) {
969183724Ssos	    //if ((err & 0x7f) == ATA_E_ILI) {
970183724Ssos		return ATA_IDX_INB(ch, ATA_COUNT) |
971183724Ssos		       (ATA_IDX_INB(ch, ATA_SECTOR) << 8) |
972183724Ssos		       (ATA_IDX_INB(ch, ATA_CYL_LSB) << 16) |
973183724Ssos		       (ATA_IDX_INB(ch, ATA_CYL_MSB) << 24);
974183724Ssos	    //}
975183724Ssos	    //else if (stat & 0x0f) {
976183724Ssos		//stat |= ATA_S_BUSY;
977183724Ssos	    //}
978183724Ssos	}
979183724Ssos
980183724Ssos	if (!(stat & ATA_S_BUSY) || (stat == 0xff && timeout > 10))
981183724Ssos	    break;
982183724Ssos	ata_udelay(100000);
983183724Ssos    }
984183724Ssos    return -1;
985183724Ssos}
986183724Ssos
987183724Ssosstatic void
988183724Ssosata_promise_mio_dmainit(device_t dev)
989183724Ssos{
990183724Ssos    struct ata_channel *ch = device_get_softc(dev);
991183724Ssos
992183724Ssos    /* note start and stop are not used here */
993183724Ssos    ch->dma.setprd = ata_promise_mio_setprd;
994200607Smav    ch->dma.max_iosize = 65536;
995216013Smarius    ata_dmainit(dev);
996183724Ssos}
997183724Ssos
998183724Ssos#define MAXLASTSGSIZE (32 * sizeof(u_int32_t))
999183724Ssosstatic void
1000183724Ssosata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
1001183724Ssos{
1002183724Ssos    struct ata_dmasetprd_args *args = xsc;
1003183724Ssos    struct ata_dma_prdentry *prd = args->dmatab;
1004183724Ssos    int i;
1005183724Ssos
1006183724Ssos    if ((args->error = error))
1007183724Ssos	return;
1008183724Ssos
1009183724Ssos    for (i = 0; i < nsegs; i++) {
1010183724Ssos	prd[i].addr = htole32(segs[i].ds_addr);
1011183724Ssos	prd[i].count = htole32(segs[i].ds_len);
1012183724Ssos    }
1013183724Ssos    if (segs[i - 1].ds_len > MAXLASTSGSIZE) {
1014183724Ssos	//printf("split last SG element of %u\n", segs[i - 1].ds_len);
1015183724Ssos	prd[i - 1].count = htole32(segs[i - 1].ds_len - MAXLASTSGSIZE);
1016183724Ssos	prd[i].count = htole32(MAXLASTSGSIZE);
1017183724Ssos	prd[i].addr = htole32(segs[i - 1].ds_addr +
1018183724Ssos			      (segs[i - 1].ds_len - MAXLASTSGSIZE));
1019183724Ssos	nsegs++;
1020183724Ssos	i++;
1021183724Ssos    }
1022183724Ssos    prd[i - 1].count |= htole32(ATA_DMA_EOT);
1023183724Ssos    KASSERT(nsegs <= ATA_DMA_ENTRIES, ("too many DMA segment entries\n"));
1024183724Ssos    args->nsegs = nsegs;
1025183724Ssos}
1026183724Ssos
1027200171Smavstatic int
1028200171Smavata_promise_mio_setmode(device_t dev, int target, int mode)
1029183724Ssos{
1030200171Smav        struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
1031200171Smav        struct ata_channel *ch = device_get_softc(dev);
1032183724Ssos
1033200171Smav        if ( (ctlr->chip->cfg2 == PR_SATA) ||
1034200171Smav    	    ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) ||
1035203034Smav	     (ctlr->chip->cfg2 == PR_SATA2) ||
1036200171Smav	    ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2)))
1037200171Smav		mode = ata_sata_setmode(dev, target, mode);
1038200171Smav	else
1039200171Smav		mode = ata_promise_setmode(dev, target, mode);
1040200171Smav	return (mode);
1041183724Ssos}
1042183724Ssos
1043203034Smavstatic int
1044203034Smavata_promise_mio_getrev(device_t dev, int target)
1045203034Smav{
1046203034Smav        struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
1047203034Smav        struct ata_channel *ch = device_get_softc(dev);
1048203034Smav
1049203034Smav        if ( (ctlr->chip->cfg2 == PR_SATA) ||
1050203034Smav    	    ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) ||
1051203034Smav	     (ctlr->chip->cfg2 == PR_SATA2) ||
1052203034Smav	    ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2)))
1053203034Smav		return (ata_sata_getrev(dev, target));
1054203034Smav	else
1055203034Smav		return (0);
1056203034Smav}
1057203034Smav
1058183724Ssosstatic void
1059183724Ssosata_promise_sx4_intr(void *data)
1060183724Ssos{
1061183724Ssos    struct ata_pci_controller *ctlr = data;
1062183724Ssos    struct ata_channel *ch;
1063183724Ssos    u_int32_t vector = ATA_INL(ctlr->r_res2, 0x000c0480);
1064183724Ssos    int unit;
1065183724Ssos
1066183724Ssos    for (unit = 0; unit < ctlr->channels; unit++) {
1067183724Ssos	if (vector & (1 << (unit + 1)))
1068183724Ssos	    if ((ch = ctlr->interrupt[unit].argument))
1069183724Ssos		ctlr->interrupt[unit].function(ch);
1070183724Ssos	if (vector & (1 << (unit + 5)))
1071183724Ssos	    if ((ch = ctlr->interrupt[unit].argument))
1072183724Ssos		ata_promise_queue_hpkt(ctlr,
1073183724Ssos				       htole32((ch->unit * ATA_PDC_CHN_OFFSET) +
1074183724Ssos					       ATA_PDC_HPKT_OFFSET));
1075183724Ssos	if (vector & (1 << (unit + 9))) {
1076183724Ssos	    ata_promise_next_hpkt(ctlr);
1077183724Ssos	    if ((ch = ctlr->interrupt[unit].argument))
1078183724Ssos		ctlr->interrupt[unit].function(ch);
1079183724Ssos	}
1080183724Ssos	if (vector & (1 << (unit + 13))) {
1081183724Ssos	    ata_promise_next_hpkt(ctlr);
1082183724Ssos	    if ((ch = ctlr->interrupt[unit].argument))
1083183724Ssos		ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7),
1084183724Ssos			 htole32((ch->unit * ATA_PDC_CHN_OFFSET) +
1085183724Ssos			 ATA_PDC_APKT_OFFSET));
1086183724Ssos	}
1087183724Ssos    }
1088183724Ssos}
1089183724Ssos
1090183724Ssosstatic int
1091183724Ssosata_promise_sx4_command(struct ata_request *request)
1092183724Ssos{
1093198717Smav    device_t gparent = device_get_parent(request->parent);
1094183724Ssos    struct ata_pci_controller *ctlr = device_get_softc(gparent);
1095183724Ssos    struct ata_channel *ch = device_get_softc(request->parent);
1096192433Smav    struct ata_dma_prdentry *prd;
1097183724Ssos    caddr_t window = rman_get_virtual(ctlr->r_res1);
1098183724Ssos    u_int32_t *wordp;
1099183724Ssos    int i, idx, length = 0;
1100183724Ssos
1101183724Ssos    /* XXX SOS add ATAPI commands support later */
1102183724Ssos    switch (request->u.ata.command) {
1103183724Ssos
1104183724Ssos    default:
1105183724Ssos	return -1;
1106183724Ssos
1107183724Ssos    case ATA_ATA_IDENTIFY:
1108183724Ssos    case ATA_READ:
1109183724Ssos    case ATA_READ48:
1110183724Ssos    case ATA_READ_MUL:
1111183724Ssos    case ATA_READ_MUL48:
1112183724Ssos    case ATA_WRITE:
1113183724Ssos    case ATA_WRITE48:
1114183724Ssos    case ATA_WRITE_MUL:
1115183724Ssos    case ATA_WRITE_MUL48:
1116183724Ssos	ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit + 1) << 2), 0x00000001);
1117183724Ssos	return ata_generic_command(request);
1118183724Ssos
1119183724Ssos    case ATA_SETFEATURES:
1120183724Ssos    case ATA_FLUSHCACHE:
1121183724Ssos    case ATA_FLUSHCACHE48:
1122183724Ssos    case ATA_SLEEP:
1123183724Ssos    case ATA_SET_MULTI:
1124183724Ssos	wordp = (u_int32_t *)
1125183724Ssos	    (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET);
1126183724Ssos	wordp[0] = htole32(0x08 | ((ch->unit + 1)<<16) | (0x00 << 24));
1127183724Ssos	wordp[1] = 0;
1128183724Ssos	wordp[2] = 0;
1129183724Ssos	ata_promise_apkt((u_int8_t *)wordp, request);
1130183724Ssos	ATA_OUTL(ctlr->r_res2, 0x000c0484, 0x00000001);
1131183724Ssos	ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit + 1) << 2), 0x00000001);
1132183724Ssos	ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7),
1133183724Ssos		 htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_APKT_OFFSET));
1134183724Ssos	return 0;
1135183724Ssos
1136183724Ssos    case ATA_READ_DMA:
1137183724Ssos    case ATA_READ_DMA48:
1138183724Ssos    case ATA_WRITE_DMA:
1139183724Ssos    case ATA_WRITE_DMA48:
1140192433Smav	prd = request->dma->sg;
1141183724Ssos	wordp = (u_int32_t *)
1142183724Ssos	    (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HSG_OFFSET);
1143183724Ssos	i = idx = 0;
1144183724Ssos	do {
1145183724Ssos	    wordp[idx++] = prd[i].addr;
1146183724Ssos	    wordp[idx++] = prd[i].count;
1147183724Ssos	    length += (prd[i].count & ~ATA_DMA_EOT);
1148183724Ssos	} while (!(prd[i++].count & ATA_DMA_EOT));
1149183724Ssos
1150183724Ssos	wordp = (u_int32_t *)
1151183724Ssos	    (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_LSG_OFFSET);
1152183724Ssos	wordp[0] = htole32((ch->unit * ATA_PDC_BUF_OFFSET) + ATA_PDC_BUF_BASE);
1153183724Ssos	wordp[1] = htole32(request->bytecount | ATA_DMA_EOT);
1154183724Ssos
1155183724Ssos	wordp = (u_int32_t *)
1156183724Ssos	    (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_ASG_OFFSET);
1157183724Ssos	wordp[0] = htole32((ch->unit * ATA_PDC_BUF_OFFSET) + ATA_PDC_BUF_BASE);
1158183724Ssos	wordp[1] = htole32(request->bytecount | ATA_DMA_EOT);
1159183724Ssos
1160183724Ssos	wordp = (u_int32_t *)
1161183724Ssos	    (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HPKT_OFFSET);
1162183724Ssos	if (request->flags & ATA_R_READ)
1163183724Ssos	    wordp[0] = htole32(0x14 | ((ch->unit+9)<<16) | ((ch->unit+5)<<24));
1164183724Ssos	if (request->flags & ATA_R_WRITE)
1165183724Ssos	    wordp[0] = htole32(0x00 | ((ch->unit+13)<<16) | (0x00<<24));
1166183724Ssos	wordp[1] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_HSG_OFFSET);
1167183724Ssos	wordp[2] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_LSG_OFFSET);
1168183724Ssos	wordp[3] = 0;
1169183724Ssos
1170183724Ssos	wordp = (u_int32_t *)
1171183724Ssos	    (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET);
1172183724Ssos	if (request->flags & ATA_R_READ)
1173183724Ssos	    wordp[0] = htole32(0x04 | ((ch->unit+5)<<16) | (0x00<<24));
1174183724Ssos	if (request->flags & ATA_R_WRITE)
1175183724Ssos	    wordp[0] = htole32(0x10 | ((ch->unit+1)<<16) | ((ch->unit+13)<<24));
1176183724Ssos	wordp[1] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_ASG_OFFSET);
1177183724Ssos	wordp[2] = 0;
1178183724Ssos	ata_promise_apkt((u_int8_t *)wordp, request);
1179183724Ssos	ATA_OUTL(ctlr->r_res2, 0x000c0484, 0x00000001);
1180183724Ssos
1181183724Ssos	if (request->flags & ATA_R_READ) {
1182183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+5)<<2), 0x00000001);
1183183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+9)<<2), 0x00000001);
1184183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7),
1185183724Ssos		htole32((ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET));
1186183724Ssos	}
1187183724Ssos	if (request->flags & ATA_R_WRITE) {
1188183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+1)<<2), 0x00000001);
1189183724Ssos	    ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+13)<<2), 0x00000001);
1190183724Ssos	    ata_promise_queue_hpkt(ctlr,
1191183724Ssos		htole32((ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HPKT_OFFSET));
1192183724Ssos	}
1193183724Ssos	return 0;
1194183724Ssos    }
1195183724Ssos}
1196183724Ssos
1197183724Ssosstatic int
1198183724Ssosata_promise_apkt(u_int8_t *bytep, struct ata_request *request)
1199183724Ssos{
1200183724Ssos    int i = 12;
1201183724Ssos
1202183724Ssos    bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_PDC_WAIT_NBUSY|ATA_DRIVE;
1203198717Smav    bytep[i++] = ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit);
1204183724Ssos    bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_CTL;
1205183724Ssos    bytep[i++] = ATA_A_4BIT;
1206183724Ssos
1207198717Smav    if (request->flags & ATA_R_48BIT) {
1208183724Ssos	bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_FEATURE;
1209183724Ssos	bytep[i++] = request->u.ata.feature >> 8;
1210183724Ssos	bytep[i++] = request->u.ata.feature;
1211183724Ssos	bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_COUNT;
1212183724Ssos	bytep[i++] = request->u.ata.count >> 8;
1213183724Ssos	bytep[i++] = request->u.ata.count;
1214183724Ssos	bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_SECTOR;
1215183724Ssos	bytep[i++] = request->u.ata.lba >> 24;
1216183724Ssos	bytep[i++] = request->u.ata.lba;
1217183724Ssos	bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_CYL_LSB;
1218183724Ssos	bytep[i++] = request->u.ata.lba >> 32;
1219183724Ssos	bytep[i++] = request->u.ata.lba >> 8;
1220183724Ssos	bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_CYL_MSB;
1221183724Ssos	bytep[i++] = request->u.ata.lba >> 40;
1222183724Ssos	bytep[i++] = request->u.ata.lba >> 16;
1223183724Ssos	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE;
1224198717Smav	bytep[i++] = ATA_D_LBA | ATA_DEV(request->unit);
1225183724Ssos    }
1226183724Ssos    else {
1227183724Ssos	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_FEATURE;
1228183724Ssos	bytep[i++] = request->u.ata.feature;
1229183724Ssos	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_COUNT;
1230183724Ssos	bytep[i++] = request->u.ata.count;
1231183724Ssos	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_SECTOR;
1232183724Ssos	bytep[i++] = request->u.ata.lba;
1233183724Ssos	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_LSB;
1234183724Ssos	bytep[i++] = request->u.ata.lba >> 8;
1235183724Ssos	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_MSB;
1236183724Ssos	bytep[i++] = request->u.ata.lba >> 16;
1237183724Ssos	bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE;
1238198717Smav	bytep[i++] = ATA_D_LBA | ATA_D_IBM | ATA_DEV(request->unit) |
1239183724Ssos		     ((request->u.ata.lba >> 24)&0xf);
1240183724Ssos    }
1241183724Ssos    bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_END | ATA_COMMAND;
1242183724Ssos    bytep[i++] = request->u.ata.command;
1243183724Ssos    return i;
1244183724Ssos}
1245183724Ssos
1246183724Ssosstatic void
1247183724Ssosata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt)
1248183724Ssos{
1249192105Sjhb    struct ata_promise_sx4 *hpktp = ctlr->chipset_data;
1250183724Ssos
1251183724Ssos    mtx_lock(&hpktp->mtx);
1252183724Ssos    if (hpktp->busy) {
1253183724Ssos	struct host_packet *hp =
1254183724Ssos	    malloc(sizeof(struct host_packet), M_TEMP, M_NOWAIT | M_ZERO);
1255183724Ssos	hp->addr = hpkt;
1256183724Ssos	TAILQ_INSERT_TAIL(&hpktp->queue, hp, chain);
1257183724Ssos    }
1258183724Ssos    else {
1259183724Ssos	hpktp->busy = 1;
1260183724Ssos	ATA_OUTL(ctlr->r_res2, 0x000c0100, hpkt);
1261183724Ssos    }
1262183724Ssos    mtx_unlock(&hpktp->mtx);
1263183724Ssos}
1264183724Ssos
1265183724Ssosstatic void
1266183724Ssosata_promise_next_hpkt(struct ata_pci_controller *ctlr)
1267183724Ssos{
1268192105Sjhb    struct ata_promise_sx4 *hpktp = ctlr->chipset_data;
1269183724Ssos    struct host_packet *hp;
1270183724Ssos
1271183724Ssos    mtx_lock(&hpktp->mtx);
1272183724Ssos    if ((hp = TAILQ_FIRST(&hpktp->queue))) {
1273183724Ssos	TAILQ_REMOVE(&hpktp->queue, hp, chain);
1274183724Ssos	ATA_OUTL(ctlr->r_res2, 0x000c0100, hp->addr);
1275183724Ssos	free(hp, M_TEMP);
1276183724Ssos    }
1277183724Ssos    else
1278183724Ssos	hpktp->busy = 0;
1279183724Ssos    mtx_unlock(&hpktp->mtx);
1280183724Ssos}
1281183724Ssos
1282183724SsosATA_DECLARE_DRIVER(ata_promise);
1283