]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/arm/mv/mv_sata.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / arm / mv / mv_sata.c
1 /*-
2  * Copyright (C) 2008-2009 Semihalf
3  * All rights reserved.
4  *
5  * Initial version developed by Ilya Bakulin. Full functionality and bringup
6  * by Piotr Ziecik.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/param.h>
34 #include <sys/bus.h>
35 #include <sys/lock.h>
36 #include <sys/resource.h>
37 #include <sys/systm.h>
38 #include <sys/rman.h>
39 #include <sys/kernel.h>
40 #include <sys/module.h>
41 #include <sys/mutex.h>
42 #include <sys/endian.h>
43 #include <sys/sema.h>
44 #include <sys/taskqueue.h>
45 #include <vm/uma.h>
46 #include <machine/bus.h>
47 #include <machine/resource.h>
48
49 #include <sys/ata.h>
50 #include <dev/ata/ata-all.h>
51 #include <dev/ofw/ofw_bus.h>
52 #include <dev/ofw/ofw_bus_subr.h>
53
54 #include "ata_if.h"
55
56 #include "mvreg.h"
57 #include "mvvar.h"
58
59 /* Useful macros */
60 #define EDMA_TIMEOUT            100000 /* 100 ms */
61 #define SATA_INL(sc, reg)       ATA_INL((sc)->sc_mem_res, reg)
62 #define SATA_OUTL(sc, reg, val) ATA_OUTL((sc)->sc_mem_res, reg, val)
63
64 /* HW-related data structures */
65 struct sata_prdentry {
66         uint32_t        prd_addrlo;
67         uint32_t        prd_count;
68         uint32_t        prd_addrhi;
69         uint32_t        prd_reserved;
70 };
71
72 struct sata_crqb {
73         uint32_t        crqb_prdlo;
74         uint32_t        crqb_prdhi;
75         uint32_t        crqb_flags;
76         uint16_t        crqb_count;
77         uint16_t        crqb_reserved1[2];
78         uint8_t         crqb_ata_command;
79         uint8_t         crqb_ata_feature;
80         uint8_t         crqb_ata_lba_low;
81         uint8_t         crqb_ata_lba_mid;
82         uint8_t         crqb_ata_lba_high;
83         uint8_t         crqb_ata_device;
84         uint8_t         crqb_ata_lba_low_p;
85         uint8_t         crqb_ata_lba_mid_p;
86         uint8_t         crqb_ata_lba_high_p;
87         uint8_t         crqb_ata_feature_p;
88         uint8_t         crqb_ata_count;
89         uint8_t         crqb_ata_count_p;
90         uint16_t        crqb_reserved2;
91 };
92
93 struct sata_crpb {
94         uint8_t         crpb_tag;
95         uint8_t         crpb_reserved;
96         uint8_t         crpb_edma_status;
97         uint8_t         crpb_dev_status;
98         uint32_t        crpb_timestamp;
99 };
100
101 /* Identification section. */
102 struct sata_softc {
103         device_t                sc_dev;
104         unsigned int            sc_version;
105         unsigned int            sc_edma_qlen;
106         uint32_t                sc_edma_reqis_mask;
107         uint32_t                sc_edma_resos_mask;
108         struct resource         *sc_mem_res;
109         bus_space_tag_t         sc_mem_res_bustag;
110         bus_space_handle_t      sc_mem_res_bushdl;
111         struct resource         *sc_irq_res;
112         void                    *sc_irq_cookiep;
113         struct {
114                 void    (*function)(void *);
115                 void    *argument;
116         } sc_interrupt[SATA_CHAN_NUM];
117 };
118
119 /* Controller functions */
120 static int      sata_probe(device_t dev);
121 static int      sata_attach(device_t dev);
122 static int      sata_detach(device_t dev);
123 static void     sata_intr(void*);
124 static struct resource * sata_alloc_resource(device_t dev, device_t child,
125     int type, int *rid, u_long start, u_long end, u_long count, u_int flags);
126 static int      sata_release_resource(device_t dev, device_t child, int type,
127     int rid, struct resource *r);
128 static int      sata_setup_intr(device_t dev, device_t child,
129     struct resource *irq, int flags, driver_filter_t *filt,
130     driver_intr_t *function, void *argument, void **cookiep);
131 static int      sata_teardown_intr(device_t dev, device_t child,
132     struct resource *irq, void *cookie);
133
134 /* Channel functions */
135 static int      sata_channel_probe(device_t dev);
136 static int      sata_channel_attach(device_t dev);
137 static int      sata_channel_detach(device_t dev);
138 static int      sata_channel_begin_transaction(struct ata_request *request);
139 static int      sata_channel_end_transaction(struct ata_request *request);
140 static int      sata_channel_status(device_t dev);
141 static int      sata_channel_setmode(device_t dev, int target, int mode);
142 static int      sata_channel_getrev(device_t dev, int target);
143 static void     sata_channel_reset(device_t dev);
144 static void     sata_channel_dmasetprd(void *xsc, bus_dma_segment_t *segs,
145     int nsegs, int error);
146
147 /* EDMA functions */
148 static int      sata_edma_ctrl(device_t dev, int on);
149 static int      sata_edma_is_running(device_t);
150
151 static device_method_t sata_methods[] = {
152         /* Device method */
153         DEVMETHOD(device_probe,         sata_probe),
154         DEVMETHOD(device_attach,        sata_attach),
155         DEVMETHOD(device_detach,        sata_detach),
156         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
157         DEVMETHOD(device_suspend,       bus_generic_suspend),
158         DEVMETHOD(device_resume,        bus_generic_resume),
159
160         /* ATA bus methods. */
161         DEVMETHOD(bus_alloc_resource,           sata_alloc_resource),
162         DEVMETHOD(bus_release_resource,         sata_release_resource),
163         DEVMETHOD(bus_activate_resource,        bus_generic_activate_resource),
164         DEVMETHOD(bus_deactivate_resource,      bus_generic_deactivate_resource),
165         DEVMETHOD(bus_setup_intr,               sata_setup_intr),
166         DEVMETHOD(bus_teardown_intr,            sata_teardown_intr),
167         { 0, 0 },
168 };
169
170 static driver_t sata_driver = {
171         "sata",
172         sata_methods,
173         sizeof(struct sata_softc),
174 };
175
176 devclass_t sata_devclass;
177
178 DRIVER_MODULE(sata, simplebus, sata_driver, sata_devclass, 0, 0);
179 MODULE_VERSION(sata, 1);
180 MODULE_DEPEND(sata, ata, 1, 1, 1);
181
182 static int
183 sata_probe(device_t dev)
184 {
185         struct sata_softc *sc;
186         uint32_t d, r;
187
188         if (!ofw_bus_status_okay(dev))
189                 return (ENXIO);
190
191         if (!ofw_bus_is_compatible(dev, "mrvl,sata"))
192                 return (ENXIO);
193
194         soc_id(&d, &r);
195         sc = device_get_softc(dev);
196
197         switch(d) {
198         case MV_DEV_88F5182:
199                 sc->sc_version = 1;
200                 sc->sc_edma_qlen = 128;
201                 break;
202         case MV_DEV_88F6281:
203         case MV_DEV_88F6282:
204         case MV_DEV_MV78100:
205         case MV_DEV_MV78100_Z0:
206         case MV_DEV_MV78460:
207                 sc->sc_version = 2;
208                 sc->sc_edma_qlen = 32;
209                 break;
210         default:
211                 device_printf(dev, "unsupported SoC (ID: 0x%08X)!\n", d);
212                 return (ENXIO);
213         }
214
215         sc->sc_edma_reqis_mask = (sc->sc_edma_qlen - 1) << SATA_EDMA_REQIS_OFS;
216         sc->sc_edma_resos_mask = (sc->sc_edma_qlen - 1) << SATA_EDMA_RESOS_OFS;
217
218         device_set_desc(dev, "Marvell Integrated SATA Controller");
219         return (0);
220 }
221
222 static int
223 sata_attach(device_t dev)
224 {
225         struct sata_softc *sc;
226         int mem_id, irq_id, error, i;
227         device_t ata_chan;
228         uint32_t reg;
229
230         sc = device_get_softc(dev);
231         sc->sc_dev = dev;
232         mem_id = 0;
233         irq_id = 0;
234
235         /* Allocate resources */
236         sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
237             &mem_id, RF_ACTIVE);
238         if (sc->sc_mem_res == NULL) {
239                 device_printf(dev, "could not allocate memory.\n");
240                 return (ENOMEM);
241         }
242
243         sc->sc_mem_res_bustag = rman_get_bustag(sc->sc_mem_res);
244         sc->sc_mem_res_bushdl = rman_get_bushandle(sc->sc_mem_res);
245         KASSERT(sc->sc_mem_res_bustag && sc->sc_mem_res_bushdl,
246             ("cannot get bus handle or tag."));
247
248         sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irq_id,
249             RF_ACTIVE);
250         if (sc->sc_irq_res == NULL) {
251                 device_printf(dev, "could not allocate IRQ.\n");
252                 error = ENOMEM;
253                 goto err;
254         }
255
256         error = bus_setup_intr(dev, sc->sc_irq_res,
257             INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY,
258             NULL, sata_intr, sc, &sc->sc_irq_cookiep);
259         if (error != 0) {
260                 device_printf(dev, "could not setup interrupt.\n");
261                 goto err;
262         }
263
264         /* Attach channels */
265         for (i = 0; i < SATA_CHAN_NUM; i++) {
266                 ata_chan = device_add_child(dev, "ata",
267                     devclass_find_free_unit(ata_devclass, 0));
268
269                 if (!ata_chan) {
270                         device_printf(dev, "cannot add channel %d.\n", i);
271                         error = ENOMEM;
272                         goto err;
273                 }
274         }
275
276         /* Disable interrupt coalescing */
277         reg = SATA_INL(sc, SATA_CR);
278         for (i = 0; i < SATA_CHAN_NUM; i++)
279                 reg |= SATA_CR_COALDIS(i);
280
281         /* Disable DMA byte swapping */
282         if (sc->sc_version == 2)
283                 reg |= SATA_CR_NODMABS | SATA_CR_NOEDMABS |
284                     SATA_CR_NOPRDPBS;
285
286         SATA_OUTL(sc, SATA_CR, reg);
287
288         /* Clear and mask all interrupts */
289         SATA_OUTL(sc, SATA_ICR, 0);
290         SATA_OUTL(sc, SATA_MIMR, 0);
291
292         return(bus_generic_attach(dev));
293
294 err:
295         sata_detach(dev);
296         return (error);
297 }
298
299 static int
300 sata_detach(device_t dev)
301 {
302         struct sata_softc *sc;
303
304         sc = device_get_softc(dev);
305
306         if (device_is_attached(dev))
307                 bus_generic_detach(dev);
308
309         if (sc->sc_mem_res != NULL) {
310                 bus_release_resource(dev, SYS_RES_MEMORY,
311                     rman_get_rid(sc->sc_mem_res), sc->sc_mem_res);
312                 sc->sc_mem_res = NULL;
313         }
314
315         if (sc->sc_irq_res != NULL) {
316                 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_cookiep);
317                 bus_release_resource(dev, SYS_RES_IRQ,
318                     rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
319                 sc->sc_irq_res = NULL;
320         }
321
322         return (0);
323 }
324
325 static struct resource *
326 sata_alloc_resource(device_t dev, device_t child, int type, int *rid,
327     u_long start, u_long end, u_long count, u_int flags)
328 {
329         struct sata_softc *sc;
330
331         sc = device_get_softc(dev);
332
333         KASSERT(type == SYS_RES_IRQ && *rid == ATA_IRQ_RID,
334             ("illegal resource request (type %u, rid %u).",
335             type, *rid));
336
337         return (sc->sc_irq_res);
338 }
339
340 static int
341 sata_release_resource(device_t dev, device_t child, int type, int rid,
342     struct resource *r)
343 {
344
345         KASSERT(type == SYS_RES_IRQ && rid == ATA_IRQ_RID,
346             ("strange type %u and/or rid %u while releasing resource.", type,
347             rid));
348
349         return (0);
350 }
351
352 static int
353 sata_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
354     driver_filter_t *filt, driver_intr_t *function, void *argument,
355     void **cookiep)
356 {
357         struct sata_softc *sc;
358         struct ata_channel *ch;
359
360         sc = device_get_softc(dev);
361         ch = device_get_softc(child);
362
363         if (filt != NULL) {
364                 device_printf(dev, "filter interrupts are not supported.\n");
365                 return (EINVAL);
366         }
367
368         sc->sc_interrupt[ch->unit].function = function;
369         sc->sc_interrupt[ch->unit].argument = argument;
370         *cookiep = sc;
371
372         return (0);
373 }
374
375 static int
376 sata_teardown_intr(device_t dev, device_t child, struct resource *irq,
377     void *cookie)
378 {
379         struct sata_softc *sc;
380         struct ata_channel *ch;
381
382         sc = device_get_softc(dev);
383         ch = device_get_softc(child);
384
385         sc->sc_interrupt[ch->unit].function = NULL;
386         sc->sc_interrupt[ch->unit].argument = NULL;
387
388         return (0);
389 }
390
391 static void
392 sata_intr(void *xsc)
393 {
394         struct sata_softc *sc;
395         int unit;
396
397         sc = xsc;
398
399         /*
400          * Behave like ata_generic_intr() for PCI controllers.
401          * Simply invoke ISRs on all channels.
402          */
403         for (unit = 0; unit < SATA_CHAN_NUM; unit++)
404                 if (sc->sc_interrupt[unit].function != NULL)
405                         sc->sc_interrupt[unit].function(
406                             sc->sc_interrupt[unit].argument);
407 }
408
409 static int
410 sata_channel_probe(device_t dev)
411 {
412
413         device_set_desc(dev, "Marvell Integrated SATA Channel");
414         return (ata_probe(dev));
415 }
416
417 static int
418 sata_channel_attach(device_t dev)
419 {
420         struct sata_softc *sc;
421         struct ata_channel *ch;
422         uint64_t work;
423         int error, i;
424
425         sc = device_get_softc(device_get_parent(dev));
426         ch = device_get_softc(dev);
427
428         if (ch->attached)
429                 return (0);
430
431         ch->dev = dev;
432         ch->unit = device_get_unit(dev);
433         ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE | ATA_SATA;
434
435         /* Set legacy ATA resources. */
436         for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
437                 ch->r_io[i].res = sc->sc_mem_res;
438                 ch->r_io[i].offset = SATA_SHADOWR_BASE(ch->unit) + (i << 2);
439         }
440
441         ch->r_io[ATA_CONTROL].res = sc->sc_mem_res;
442         ch->r_io[ATA_CONTROL].offset = SATA_SHADOWR_CONTROL(ch->unit);
443
444         ch->r_io[ATA_IDX_ADDR].res = sc->sc_mem_res;
445         ata_default_registers(dev);
446
447         /* Set SATA resources. */
448         ch->r_io[ATA_SSTATUS].res = sc->sc_mem_res;
449         ch->r_io[ATA_SSTATUS].offset = SATA_SATA_SSTATUS(ch->unit);
450         ch->r_io[ATA_SERROR].res = sc->sc_mem_res;
451         ch->r_io[ATA_SERROR].offset = SATA_SATA_SERROR(ch->unit);
452         ch->r_io[ATA_SCONTROL].res = sc->sc_mem_res;
453         ch->r_io[ATA_SCONTROL].offset = SATA_SATA_SCONTROL(ch->unit);
454         ata_generic_hw(dev);
455
456         ch->hw.begin_transaction = sata_channel_begin_transaction;
457         ch->hw.end_transaction = sata_channel_end_transaction;
458         ch->hw.status = sata_channel_status;
459
460         /* Set DMA resources */
461         ata_dmainit(dev);
462         ch->dma.setprd = sata_channel_dmasetprd;
463
464         /* Clear work area */
465         KASSERT(sc->sc_edma_qlen * (sizeof(struct sata_crqb) +
466             sizeof(struct sata_crpb)) <= ch->dma.max_iosize,
467             ("insufficient DMA memory for request/response queues.\n"));
468         bzero(ch->dma.work, sc->sc_edma_qlen * (sizeof(struct sata_crqb) +
469             sizeof(struct sata_crpb)));
470         bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
471             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
472
473         /* Turn off EDMA engine */
474         error = sata_edma_ctrl(dev, 0);
475         if (error) {
476                 ata_dmafini(dev);
477                 return (error);
478         }
479
480         /*
481          * Initialize EDMA engine:
482          *      - Native Command Queuing off,
483          *      - Non-Queued operation,
484          *      - Host Queue Cache enabled.
485          */
486         SATA_OUTL(sc, SATA_EDMA_CFG(ch->unit), SATA_EDMA_CFG_HQCACHE |
487             (sc->sc_version == 1) ? SATA_EDMA_CFG_QL128 : 0);
488
489         /* Set request queue pointers */
490         work = ch->dma.work_bus;
491         SATA_OUTL(sc, SATA_EDMA_REQBAHR(ch->unit), work >> 32);
492         SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), work & 0xFFFFFFFF);
493         SATA_OUTL(sc, SATA_EDMA_REQOPR(ch->unit), work & 0xFFFFFFFF);
494
495         /* Set response queue pointers */
496         work += sc->sc_edma_qlen * sizeof(struct sata_crqb);
497         SATA_OUTL(sc, SATA_EDMA_RESBAHR(ch->unit), work >> 32);
498         SATA_OUTL(sc, SATA_EDMA_RESIPR(ch->unit), work & 0xFFFFFFFF);
499         SATA_OUTL(sc, SATA_EDMA_RESOPR(ch->unit), work & 0xFFFFFFFF);
500
501         /* Clear any outstanding interrupts */
502         ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR));
503         SATA_OUTL(sc, SATA_SATA_FISICR(ch->unit), 0);
504         SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
505         SATA_OUTL(sc, SATA_ICR,
506             ~(SATA_ICR_DEV(ch->unit) | SATA_ICR_DMADONE(ch->unit)));
507
508         /* Umask channel interrupts */
509         SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF);
510         SATA_OUTL(sc, SATA_MIMR, SATA_INL(sc, SATA_MIMR) |
511             SATA_MICR_DONE(ch->unit) | SATA_MICR_DMADONE(ch->unit) |
512             SATA_MICR_ERR(ch->unit));
513
514         ch->attached = 1;
515
516         return (ata_attach(dev));
517 }
518
519 static int
520 sata_channel_detach(device_t dev)
521 {
522         struct sata_softc *sc;
523         struct ata_channel *ch;
524         int error;
525
526         sc = device_get_softc(device_get_parent(dev));
527         ch = device_get_softc(dev);
528
529         if (!ch->attached)
530                 return (0);
531
532         /* Turn off EDMA engine */
533         sata_edma_ctrl(dev, 0);
534
535         /* Mask chanel interrupts */
536         SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0);
537         SATA_OUTL(sc, SATA_MIMR, SATA_INL(sc, SATA_MIMR) & ~(
538             SATA_MICR_DONE(ch->unit) | SATA_MICR_DMADONE(ch->unit) |
539             SATA_MICR_ERR(ch->unit)));
540
541         error = ata_detach(dev);
542         ata_dmafini(dev);
543
544         ch->attached = 0;
545
546         return (error);
547 }
548
549 static int
550 sata_channel_begin_transaction(struct ata_request *request)
551 {
552         struct sata_softc *sc;
553         struct ata_channel *ch;
554         struct sata_crqb *crqb;
555         uint32_t req_in;
556         int error, slot;
557
558         sc = device_get_softc(device_get_parent(request->parent));
559         ch = device_get_softc(request->parent);
560
561         mtx_assert(&ch->state_mtx, MA_OWNED);
562
563         /* Only DMA R/W goes through the EDMA machine. */
564         if (request->u.ata.command != ATA_READ_DMA &&
565             request->u.ata.command != ATA_WRITE_DMA &&
566             request->u.ata.command != ATA_READ_DMA48 &&
567             request->u.ata.command != ATA_WRITE_DMA48) {
568
569                 /* Disable EDMA before accessing legacy registers */
570                 if (sata_edma_is_running(request->parent)) {
571                         error = sata_edma_ctrl(request->parent, 0);
572                         if (error) {
573                                 request->result = error;
574                                 return (ATA_OP_FINISHED);
575                         }
576                 }
577
578                 return (ata_begin_transaction(request));
579         }
580
581         /* Prepare data for DMA */
582         if ((error = ch->dma.load(request, NULL, NULL))) {
583                 device_printf(request->parent, "setting up DMA failed!\n");
584                 request->result = error;
585                 return ATA_OP_FINISHED;
586         }
587
588         /* Get next free queue slot */
589         req_in = SATA_INL(sc, SATA_EDMA_REQIPR(ch->unit));
590         slot = (req_in & sc->sc_edma_reqis_mask) >> SATA_EDMA_REQIS_OFS;
591         crqb = (struct sata_crqb *)(ch->dma.work +
592             (slot << SATA_EDMA_REQIS_OFS));
593
594         /* Fill in request */
595         bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
596             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
597
598         crqb->crqb_prdlo = htole32((uint64_t)request->dma->sg_bus & 0xFFFFFFFF);
599         crqb->crqb_prdhi = htole32((uint64_t)request->dma->sg_bus >> 32);
600         crqb->crqb_flags = htole32((request->flags & ATA_R_READ ? 0x01 : 0x00) |
601             (request->tag << 1));
602
603         crqb->crqb_ata_command = request->u.ata.command;
604         crqb->crqb_ata_feature = request->u.ata.feature;
605         crqb->crqb_ata_lba_low = request->u.ata.lba;
606         crqb->crqb_ata_lba_mid = request->u.ata.lba >> 8;
607         crqb->crqb_ata_lba_high = request->u.ata.lba >> 16;
608         crqb->crqb_ata_device = ((request->u.ata.lba >> 24) & 0x0F) | (1 << 6);
609         crqb->crqb_ata_lba_low_p = request->u.ata.lba >> 24;
610         crqb->crqb_ata_lba_mid_p = request->u.ata.lba >> 32;
611         crqb->crqb_ata_lba_high_p = request->u.ata.lba >> 40;
612         crqb->crqb_ata_feature_p = request->u.ata.feature >> 8;
613         crqb->crqb_ata_count = request->u.ata.count;
614         crqb->crqb_ata_count_p = request->u.ata.count >> 8;
615
616         bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
617             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
618
619         /* Enable EDMA if disabled */
620         if (!sata_edma_is_running(request->parent)) {
621                 error = sata_edma_ctrl(request->parent, 1);
622                 if (error) {
623                         ch->dma.unload(request);
624                         request->result = error;
625                         return (ATA_OP_FINISHED);
626                 }
627         }
628
629         /* Tell EDMA about new request */
630         req_in = (req_in & ~sc->sc_edma_reqis_mask) | (((slot + 1) <<
631             SATA_EDMA_REQIS_OFS) & sc->sc_edma_reqis_mask);
632
633         SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), req_in);
634
635         return (ATA_OP_CONTINUES);
636 }
637
638 static int
639 sata_channel_end_transaction(struct ata_request *request)
640 {
641         struct sata_softc *sc;
642         struct ata_channel *ch;
643         struct sata_crpb *crpb;
644         uint32_t res_in, res_out, icr;
645         int slot;
646
647         sc = device_get_softc(device_get_parent(request->parent));
648         ch = device_get_softc(request->parent);
649
650         mtx_assert(&ch->state_mtx, MA_OWNED);
651
652         icr = SATA_INL(sc, SATA_ICR);
653         if (icr & SATA_ICR_DMADONE(ch->unit)) {
654                 /* Get current response slot */
655                 res_out = SATA_INL(sc, SATA_EDMA_RESOPR(ch->unit));
656                 slot = (res_out & sc->sc_edma_resos_mask) >>
657                     SATA_EDMA_RESOS_OFS;
658                 crpb = (struct sata_crpb *)(ch->dma.work +
659                     (sc->sc_edma_qlen * sizeof(struct sata_crqb)) +
660                     (slot << SATA_EDMA_RESOS_OFS));
661
662                 /* Record this request status */
663                 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
664                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
665
666                 request->status = crpb->crpb_dev_status;
667                 request->error = 0;
668
669                 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
670                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
671
672                 /* Update response queue pointer */
673                 res_out = (res_out & ~sc->sc_edma_resos_mask) | (((slot + 1) <<
674                     SATA_EDMA_RESOS_OFS) & sc->sc_edma_resos_mask);
675
676                 SATA_OUTL(sc, SATA_EDMA_RESOPR(ch->unit), res_out);
677
678                 /* Ack DMA interrupt if there is nothing more to do */
679                 res_in = SATA_INL(sc, SATA_EDMA_RESIPR(ch->unit));
680                 res_in &= sc->sc_edma_resos_mask;
681                 res_out &= sc->sc_edma_resos_mask;
682
683                 if (res_in == res_out)
684                         SATA_OUTL(sc, SATA_ICR,
685                             ~SATA_ICR_DMADONE(ch->unit));
686
687                 /* Update progress */
688                 if (!(request->status & ATA_S_ERROR) &&
689                     !(request->flags & ATA_R_TIMEOUT))
690                         request->donecount = request->bytecount;
691
692                 /* Unload DMA data */
693                 ch->dma.unload(request);
694
695                 return(ATA_OP_FINISHED);
696         }
697
698         /* Legacy ATA interrupt */
699         return (ata_end_transaction(request));
700 }
701
702 static int
703 sata_channel_status(device_t dev)
704 {
705         struct sata_softc *sc;
706         struct ata_channel *ch;
707         uint32_t icr, iecr;
708
709         sc = device_get_softc(device_get_parent(dev));
710         ch = device_get_softc(dev);
711
712         icr = SATA_INL(sc, SATA_ICR);
713         iecr = SATA_INL(sc, SATA_EDMA_IECR(ch->unit));
714
715         if ((icr & SATA_ICR_DEV(ch->unit)) || iecr) {
716                 /* Disable EDMA before accessing SATA registers */
717                 sata_edma_ctrl(dev, 0);
718                 ata_sata_phy_check_events(dev, -1);
719
720                 /* Ack device and error interrupt */
721                 SATA_OUTL(sc, SATA_ICR, ~SATA_ICR_DEV(ch->unit));
722                 SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
723         }
724
725         icr &= SATA_ICR_DEV(ch->unit) | SATA_ICR_DMADONE(ch->unit);
726         return (icr);
727 }
728
729 static void
730 sata_channel_reset(device_t dev)
731 {
732         struct sata_softc *sc;
733         struct ata_channel *ch;
734
735         sc = device_get_softc(device_get_parent(dev));
736         ch = device_get_softc(dev);
737
738         /* Disable EDMA before using legacy registers */
739         sata_edma_ctrl(dev, 0);
740
741         /* Mask all EDMA interrups */
742         SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0);
743
744         /* Reset EDMA */
745         SATA_OUTL(sc, SATA_EDMA_CMD(ch->unit), SATA_EDMA_CMD_RESET);
746         DELAY(25);
747         SATA_OUTL(sc, SATA_EDMA_CMD(ch->unit), 0);
748
749         /* Reset PHY and device */
750         if (ata_sata_phy_reset(dev, -1, 1))
751                 ata_generic_reset(dev);
752         else
753                 ch->devices = 0;
754
755         /* Clear EDMA errors */
756         SATA_OUTL(sc, SATA_SATA_FISICR(ch->unit), 0);
757         SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
758
759         /* Unmask all EDMA interrups */
760         SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF);
761 }
762
763 static int
764 sata_channel_setmode(device_t parent, int target, int mode)
765 {
766
767         /* Disable EDMA before using legacy registers */
768         sata_edma_ctrl(parent, 0);
769         return (ata_sata_setmode(parent, target, mode));
770 }
771
772 static int
773 sata_channel_getrev(device_t parent, int target)
774 {
775
776         /* Disable EDMA before using legacy registers */
777         sata_edma_ctrl(parent, 0);
778         return (ata_sata_getrev(parent, target));
779 }
780
781 static void
782 sata_channel_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs,
783     int error)
784 {
785         struct ata_dmasetprd_args *args;
786         struct sata_prdentry *prd;
787         int i;
788
789         args = xsc;
790         prd = args->dmatab;
791
792         if ((args->error = error))
793                 return;
794
795         for (i = 0; i < nsegs; i++) {
796                 prd[i].prd_addrlo = htole32(segs[i].ds_addr);
797                 prd[i].prd_addrhi = htole32((uint64_t)segs[i].ds_addr >> 32);
798                 prd[i].prd_count = htole32(segs[i].ds_len);
799         }
800
801         prd[i - 1].prd_count |= htole32(ATA_DMA_EOT);
802         KASSERT(nsegs <= ATA_DMA_ENTRIES, ("too many DMA segment entries.\n"));
803         args->nsegs = nsegs;
804 }
805
806 static int
807 sata_edma_ctrl(device_t dev, int on)
808 {
809         struct sata_softc *sc;
810         struct ata_channel *ch;
811         int bit, timeout;
812         uint32_t reg;
813
814         sc = device_get_softc(device_get_parent(dev));
815         ch = device_get_softc(dev);
816         bit = on ? SATA_EDMA_CMD_ENABLE : SATA_EDMA_CMD_DISABLE;
817         timeout = EDMA_TIMEOUT;
818
819         SATA_OUTL(sc, SATA_EDMA_CMD(ch->unit), bit);
820
821         while (1) {
822                 DELAY(1);
823
824                 reg = SATA_INL(sc, SATA_EDMA_CMD(ch->unit));
825
826                 /* Enable bit will be 1 after disable command completion */
827                 if (on && (reg & SATA_EDMA_CMD_ENABLE))
828                         break;
829
830                 /* Disable bit will be 0 after disable command completion */
831                 if (!on && !(reg & SATA_EDMA_CMD_DISABLE))
832                         break;
833
834                 if (timeout-- <= 0) {
835                         device_printf(dev, "EDMA command timeout!\n");
836                         return (ETIMEDOUT);
837                 }
838         }
839
840         return (0);
841 }
842
843 static int
844 sata_edma_is_running(device_t dev)
845 {
846         struct sata_softc *sc;
847         struct ata_channel *ch;
848
849         sc = device_get_softc(device_get_parent(dev));
850         ch = device_get_softc(dev);
851
852         return (SATA_INL(sc, SATA_EDMA_CMD(ch->unit)) & SATA_EDMA_CMD_ENABLE);
853 }
854
855 static device_method_t sata_channel_methods[] = {
856         /* Device interface. */
857         DEVMETHOD(device_probe,         sata_channel_probe),
858         DEVMETHOD(device_attach,        sata_channel_attach),
859         DEVMETHOD(device_detach,        sata_channel_detach),
860         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
861         DEVMETHOD(device_suspend,       ata_suspend),
862         DEVMETHOD(device_resume,        ata_resume),
863
864         /* ATA channel interface */
865         DEVMETHOD(ata_reset,            sata_channel_reset),
866         DEVMETHOD(ata_setmode,          sata_channel_setmode),
867         DEVMETHOD(ata_getrev,           sata_channel_getrev),
868         { 0, 0 }
869 };
870
871 driver_t sata_channel_driver = {
872         "ata",
873         sata_channel_methods,
874         sizeof(struct ata_channel),
875 };
876
877 DRIVER_MODULE(ata, sata, sata_channel_driver, ata_devclass, 0, 0);