xref: /dragonfly/sys/dev/disk/nata/ata-pci.c (revision 7bc7e232)
1 /*-
2  * Copyright (c) 1998 - 2006 S�ren Schmidt <sos@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  * $FreeBSD: src/sys/dev/ata/ata-pci.c,v 1.121 2007/02/23 12:18:33 piso Exp $
27  * $DragonFly: src/sys/dev/disk/nata/ata-pci.c,v 1.6 2007/10/19 11:53:14 tgen Exp $
28  */
29 
30 #include "opt_ata.h"
31 
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/bus_resource.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37 #include <sys/nata.h>
38 #include <sys/rman.h>
39 #include <sys/systm.h>
40 
41 #include <bus/pci/pcireg.h>
42 #include <bus/pci/pcivar.h>
43 
44 #include "ata-all.h"
45 #include "ata-pci.h"
46 #include "ata_if.h"
47 
48 /* local vars */
49 static MALLOC_DEFINE(M_ATAPCI, "ata_pci", "ATA driver PCI");
50 
51 /* misc defines */
52 #define IOMASK                  0xfffffffc
53 #define ATA_PROBE_OK            -10
54 
55 int
56 ata_legacy(device_t dev)
57 {
58     return (((pci_read_config(dev, PCIR_PROGIF, 1)&PCIP_STORAGE_IDE_MASTERDEV)&&
59 	    ((pci_read_config(dev, PCIR_PROGIF, 1) &
60 	      (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC)) !=
61 	     (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC))) ||
62 	    (!pci_read_config(dev, PCIR_BAR(0), 4) &&
63 	     !pci_read_config(dev, PCIR_BAR(1), 4) &&
64 	     !pci_read_config(dev, PCIR_BAR(2), 4) &&
65 	     !pci_read_config(dev, PCIR_BAR(3), 4)));
66 
67 }
68 
69 int
70 ata_pci_probe(device_t dev)
71 {
72     if (pci_get_class(dev) != PCIC_STORAGE)
73 	return ENXIO;
74 
75     switch (pci_get_vendor(dev)) {
76     case ATA_ACARD_ID:
77 	if (!ata_acard_ident(dev))
78 	    return ATA_PROBE_OK;
79 	break;
80     case ATA_ACER_LABS_ID:
81 	if (!ata_ali_ident(dev))
82 	    return ATA_PROBE_OK;
83 	break;
84     case ATA_AMD_ID:
85 	if (!ata_amd_ident(dev))
86 	    return ATA_PROBE_OK;
87 	break;
88     case ATA_ATI_ID:
89 	if (!ata_ati_ident(dev))
90 	    return ATA_PROBE_OK;
91 	break;
92     case ATA_CYRIX_ID:
93 	if (!ata_cyrix_ident(dev))
94 	    return ATA_PROBE_OK;
95 	break;
96     case ATA_CYPRESS_ID:
97 	if (!ata_cypress_ident(dev))
98 	    return ATA_PROBE_OK;
99 	break;
100     case ATA_HIGHPOINT_ID:
101 	if (!ata_highpoint_ident(dev))
102 	    return ATA_PROBE_OK;
103 	break;
104     case ATA_INTEL_ID:
105 	if (!ata_intel_ident(dev))
106 	    return ATA_PROBE_OK;
107 	break;
108     case ATA_ITE_ID:
109 	if (!ata_ite_ident(dev))
110 	    return ATA_PROBE_OK;
111 	break;
112     case ATA_JMICRON_ID:
113 	if (!ata_jmicron_ident(dev))
114 	    return ATA_PROBE_OK;
115 	break;
116     case ATA_MARVELL_ID:
117 	if (!ata_marvell_ident(dev))
118 	    return ATA_PROBE_OK;
119 	break;
120     case ATA_NATIONAL_ID:
121 	if (!ata_national_ident(dev))
122 	    return ATA_PROBE_OK;
123 	break;
124     case ATA_NETCELL_ID:
125 	if (!ata_netcell_ident(dev))
126 	    return ATA_PROBE_OK;
127 	break;
128     case ATA_NVIDIA_ID:
129 	if (!ata_nvidia_ident(dev))
130 	    return ATA_PROBE_OK;
131 	break;
132     case ATA_PROMISE_ID:
133 	if (!ata_promise_ident(dev))
134 	    return ATA_PROBE_OK;
135 	break;
136     case ATA_SERVERWORKS_ID:
137 	if (!ata_serverworks_ident(dev))
138 	    return ATA_PROBE_OK;
139 	break;
140     case ATA_SILICON_IMAGE_ID:
141 	if (!ata_sii_ident(dev))
142 	    return ATA_PROBE_OK;
143 	break;
144     case ATA_SIS_ID:
145 	if (!ata_sis_ident(dev))
146 	    return ATA_PROBE_OK;
147 	break;
148     case ATA_VIA_ID:
149 	if (!ata_via_ident(dev))
150 	    return ATA_PROBE_OK;
151 	break;
152     case ATA_CENATEK_ID:
153 	if (pci_get_devid(dev) == ATA_CENATEK_ROCKET) {
154 	    ata_generic_ident(dev);
155 	    device_set_desc(dev, "Cenatek Rocket Drive controller");
156 	    return ATA_PROBE_OK;
157 	}
158 	break;
159     case ATA_MICRON_ID:
160 	if (pci_get_devid(dev) == ATA_MICRON_RZ1000 ||
161 	    pci_get_devid(dev) == ATA_MICRON_RZ1001) {
162 	    ata_generic_ident(dev);
163 	    device_set_desc(dev,
164 		"RZ 100? ATA controller !WARNING! data loss/corruption risk");
165 	    return ATA_PROBE_OK;
166 	}
167 	break;
168     }
169 
170     /* unknown chipset, try generic AHCI or DMA if it seems possible */
171     if (pci_get_class(dev) == PCIC_STORAGE) {
172 	if (pci_get_subclass(dev) == PCIS_STORAGE_SATA) {
173 	    if (!ata_genahci_ident(dev))
174 		return ATA_PROBE_OK;
175 	} else if (pci_get_subclass(dev) == PCIS_STORAGE_IDE) {
176 	    if (!ata_generic_ident(dev))
177 		return ATA_PROBE_OK;
178 	}
179     }
180     return ENXIO;
181 }
182 
183 int
184 ata_pci_attach(device_t dev)
185 {
186     struct ata_pci_controller *ctlr = device_get_softc(dev);
187     u_int32_t cmd;
188     int unit;
189 
190     /* do chipset specific setups only needed once */
191     if (ata_legacy(dev) || pci_read_config(dev, PCIR_BAR(2), 4) & IOMASK)
192 	ctlr->channels = 2;
193     else
194 	ctlr->channels = 1;
195     ctlr->allocate = ata_pci_allocate;
196     ctlr->dmainit = ata_pci_dmainit;
197     ctlr->dev = dev;
198 
199     /* if needed try to enable busmastering */
200     cmd = pci_read_config(dev, PCIR_COMMAND, 2);
201     if (!(cmd & PCIM_CMD_BUSMASTEREN)) {
202 	pci_write_config(dev, PCIR_COMMAND, cmd | PCIM_CMD_BUSMASTEREN, 2);
203 	cmd = pci_read_config(dev, PCIR_COMMAND, 2);
204     }
205 
206     /* if busmastering mode "stuck" use it */
207     if ((cmd & PCIM_CMD_BUSMASTEREN) == PCIM_CMD_BUSMASTEREN) {
208 	ctlr->r_type1 = SYS_RES_IOPORT;
209 	ctlr->r_rid1 = ATA_BMADDR_RID;
210 	ctlr->r_res1 = bus_alloc_resource_any(dev, ctlr->r_type1, &ctlr->r_rid1,
211 					      RF_ACTIVE);
212     }
213 
214     if (ctlr->chipinit(dev))
215 	return ENXIO;
216 
217     /* attach all channels on this controller */
218     for (unit = 0; unit < ctlr->channels; unit++) {
219 	int freeunit = 2;
220 	if ((unit == 0 || unit == 1) && ata_legacy(dev)) {
221 	    device_add_child(dev, "ata", unit);
222 	    continue;
223 	}
224 	/* XXX TGEN devclass_find_free_unit() implementation */
225 	while (freeunit < devclass_get_maxunit(ata_devclass) &&
226 	       devclass_get_device(ata_devclass, freeunit) != NULL)
227 	    freeunit++;
228 	device_add_child(dev, "ata", freeunit);
229     }
230     bus_generic_attach(dev);
231     return 0;
232 }
233 
234 int
235 ata_pci_detach(device_t dev)
236 {
237     struct ata_pci_controller *ctlr = device_get_softc(dev);
238     device_t *children;
239     int nchildren, i;
240 
241     /* detach & delete all children */
242     if (!device_get_children(dev, &children, &nchildren)) {
243 	for (i = 0; i < nchildren; i++)
244 	    device_delete_child(dev, children[i]);
245 	kfree(children, M_TEMP);
246     }
247 
248     if (ctlr->r_irq) {
249 	bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle);
250 	bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ctlr->r_irq);
251     }
252     if (ctlr->r_res2)
253 	bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, ctlr->r_res2);
254     if (ctlr->r_res1)
255 	bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1, ctlr->r_res1);
256 
257     return 0;
258 }
259 
260 struct resource *
261 ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
262 		       u_long start, u_long end, u_long count, u_int flags)
263 {
264     struct ata_pci_controller *controller = device_get_softc(dev);
265     int unit = ((struct ata_channel *)device_get_softc(child))->unit;
266     struct resource *res = NULL;
267     int myrid;
268 
269     if (type == SYS_RES_IOPORT) {
270 	switch (*rid) {
271 	case ATA_IOADDR_RID:
272 	    if (ata_legacy(dev)) {
273 		start = (unit ? ATA_SECONDARY : ATA_PRIMARY);
274 		count = ATA_IOSIZE;
275 		end = start + count - 1;
276 	    }
277 	    myrid = PCIR_BAR(0) + (unit << 3);
278 	    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
279 				     SYS_RES_IOPORT, &myrid,
280 				     start, end, count, flags);
281 	    break;
282 
283 	case ATA_CTLADDR_RID:
284 	    if (ata_legacy(dev)) {
285 		start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_CTLOFFSET;
286 		count = ATA_CTLIOSIZE;
287 		end = start + count - 1;
288 	    }
289 	    myrid = PCIR_BAR(1) + (unit << 3);
290 	    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
291 				     SYS_RES_IOPORT, &myrid,
292 				     start, end, count, flags);
293 	    break;
294 	}
295     }
296     if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) {
297 	if (ata_legacy(dev)) {
298 	    int irq = (unit == 0 ? 14 : 15);
299 
300 	    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
301 				     SYS_RES_IRQ, rid, irq, irq, 1, flags);
302 	}
303 	else
304 	    res = controller->r_irq;
305     }
306     return res;
307 }
308 
309 int
310 ata_pci_release_resource(device_t dev, device_t child, int type, int rid,
311 			 struct resource *r)
312 {
313     int unit = ((struct ata_channel *)device_get_softc(child))->unit;
314 
315     if (type == SYS_RES_IOPORT) {
316 	switch (rid) {
317 	case ATA_IOADDR_RID:
318 	    return BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
319 					SYS_RES_IOPORT,
320 					PCIR_BAR(0) + (unit << 3), r);
321 	    break;
322 
323 	case ATA_CTLADDR_RID:
324 	    return BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
325 					SYS_RES_IOPORT,
326 					PCIR_BAR(1) + (unit << 3), r);
327 	    break;
328 	default:
329 	    return ENOENT;
330 	}
331     }
332     if (type == SYS_RES_IRQ) {
333 	if (rid != ATA_IRQ_RID)
334 	    return ENOENT;
335 
336 	if (ata_legacy(dev)) {
337 	    return BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
338 					SYS_RES_IRQ, rid, r);
339 	}
340 	else
341 	    return 0;
342     }
343     return EINVAL;
344 }
345 
346 int
347 ata_pci_setup_intr(device_t dev, device_t child, struct resource *irq,
348 		   int flags, driver_intr_t *function, void *argument,
349 		   void **cookiep)
350 {
351     if (ata_legacy(dev)) {
352 	return BUS_SETUP_INTR(device_get_parent(dev), child, irq,
353 			      flags, function, argument, cookiep, NULL);
354     }
355     else {
356 	struct ata_pci_controller *controller = device_get_softc(dev);
357 	int unit = ((struct ata_channel *)device_get_softc(child))->unit;
358 
359 	controller->interrupt[unit].function = function;
360 	controller->interrupt[unit].argument = argument;
361 	*cookiep = controller;
362 	return 0;
363     }
364 }
365 
366 int
367 ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
368 		      void *cookie)
369 {
370     if (ata_legacy(dev)) {
371 	return BUS_TEARDOWN_INTR(device_get_parent(dev), child, irq, cookie);
372     }
373     else {
374 	struct ata_pci_controller *controller = device_get_softc(dev);
375 	int unit = ((struct ata_channel *)device_get_softc(child))->unit;
376 
377 	controller->interrupt[unit].function = NULL;
378 	controller->interrupt[unit].argument = NULL;
379 	return 0;
380     }
381 }
382 
383 int
384 ata_pci_allocate(device_t dev)
385 {
386     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
387     struct ata_channel *ch = device_get_softc(dev);
388     struct resource *io = NULL, *ctlio = NULL;
389     int i, rid;
390 
391     rid = ATA_IOADDR_RID;
392     if (!(io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE)))
393 	return ENXIO;
394 
395     rid = ATA_CTLADDR_RID;
396     if (!(ctlio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,RF_ACTIVE))){
397 	bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io);
398 	return ENXIO;
399     }
400 
401     for (i = ATA_DATA; i <= ATA_COMMAND; i ++) {
402 	ch->r_io[i].res = io;
403 	ch->r_io[i].offset = i;
404     }
405     ch->r_io[ATA_CONTROL].res = ctlio;
406     ch->r_io[ATA_CONTROL].offset = ata_legacy(device_get_parent(dev)) ? 0 : 2;
407     ch->r_io[ATA_IDX_ADDR].res = io;
408     ata_default_registers(dev);
409     if (ctlr->r_res1) {
410 	for (i = ATA_BMCMD_PORT; i <= ATA_BMDTP_PORT; i++) {
411 	    ch->r_io[i].res = ctlr->r_res1;
412 	    ch->r_io[i].offset = (i - ATA_BMCMD_PORT) + (ch->unit*ATA_BMIOSIZE);
413 	}
414     }
415 
416     ata_pci_hw(dev);
417     return 0;
418 }
419 
420 void
421 ata_pci_hw(device_t dev)
422 {
423     struct ata_channel *ch = device_get_softc(dev);
424 
425     ata_generic_hw(dev);
426     ch->hw.status = ata_pci_status;
427 }
428 
429 int
430 ata_pci_status(device_t dev)
431 {
432     struct ata_channel *ch = device_get_softc(dev);
433 
434     if ((dumping || !ata_legacy(device_get_parent(dev))) &&
435 	ch->dma && ((ch->flags & ATA_ALWAYS_DMASTAT) ||
436 		    (ch->dma->flags & ATA_DMA_ACTIVE))) {
437 	int bmstat = ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
438 
439 	if ((bmstat & (ATA_BMSTAT_ACTIVE | ATA_BMSTAT_INTERRUPT)) !=
440 	    ATA_BMSTAT_INTERRUPT)
441 	    return 0;
442 	ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, bmstat & ~ATA_BMSTAT_ERROR);
443 	DELAY(1);
444     }
445     if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) {
446 	DELAY(100);
447 	if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY)
448 	    return 0;
449     }
450     return 1;
451 }
452 
453 static int
454 ata_pci_dmastart(device_t dev)
455 {
456     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
457     u_int8_t val;
458 
459     ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, (ATA_IDX_INB(ch, ATA_BMSTAT_PORT) |
460 		 (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
461     ATA_IDX_OUTL(ch, ATA_BMDTP_PORT, ch->dma->sg_bus);
462     ch->dma->flags |= ATA_DMA_ACTIVE;
463     val = ATA_IDX_INB(ch, ATA_BMCMD_PORT);
464     if (ch->dma->flags & ATA_DMA_READ)
465 	val |= ATA_BMCMD_WRITE_READ;
466     else
467 	val &= ~ATA_BMCMD_WRITE_READ;
468     ATA_IDX_OUTB(ch, ATA_BMCMD_PORT, val);
469 
470     /*
471      * Issue the start command separately from configuration setup,
472      * in case the hardware latches portions of the configuration.
473      */
474     ATA_IDX_OUTB(ch, ATA_BMCMD_PORT, val | ATA_BMCMD_START_STOP);
475 
476     return 0;
477 }
478 
479 static int
480 ata_pci_dmastop(device_t dev)
481 {
482     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
483     int error;
484 
485     ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,
486 		 ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
487     ch->dma->flags &= ~ATA_DMA_ACTIVE;
488     error = ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
489     ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);
490     return error;
491 }
492 
493 static void
494 ata_pci_dmareset(device_t dev)
495 {
496     struct ata_channel *ch = device_get_softc(dev);
497 
498     ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,
499 		 ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
500     ch->dma->flags &= ~ATA_DMA_ACTIVE;
501     ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);
502     ch->dma->unload(dev);
503 }
504 
505 void
506 ata_pci_dmainit(device_t dev)
507 {
508     struct ata_channel *ch = device_get_softc(dev);
509 
510     ata_dmainit(dev);
511     if (ch->dma) {
512 	ch->dma->start = ata_pci_dmastart;
513 	ch->dma->stop = ata_pci_dmastop;
514 	ch->dma->reset = ata_pci_dmareset;
515     }
516 }
517 
518 static device_method_t ata_pci_methods[] = {
519     /* device interface */
520     DEVMETHOD(device_probe,             ata_pci_probe),
521     DEVMETHOD(device_attach,            ata_pci_attach),
522     DEVMETHOD(device_detach,            ata_pci_detach),
523     DEVMETHOD(device_shutdown,          bus_generic_shutdown),
524     DEVMETHOD(device_suspend,           bus_generic_suspend),
525     DEVMETHOD(device_resume,            bus_generic_resume),
526 
527     /* bus methods */
528     DEVMETHOD(bus_alloc_resource,       ata_pci_alloc_resource),
529     DEVMETHOD(bus_release_resource,     ata_pci_release_resource),
530     DEVMETHOD(bus_activate_resource,    bus_generic_activate_resource),
531     DEVMETHOD(bus_deactivate_resource,  bus_generic_deactivate_resource),
532     DEVMETHOD(bus_setup_intr,           ata_pci_setup_intr),
533     DEVMETHOD(bus_teardown_intr,        ata_pci_teardown_intr),
534 
535     { 0, 0 }
536 };
537 
538 devclass_t atapci_devclass;
539 
540 static driver_t ata_pci_driver = {
541     "atapci",
542     ata_pci_methods,
543     sizeof(struct ata_pci_controller),
544 };
545 
546 DRIVER_MODULE(atapci, pci, ata_pci_driver, atapci_devclass, 0, 0);
547 MODULE_VERSION(atapci, 1);
548 MODULE_DEPEND(atapci, ata, 1, 1, 1);
549 
550 static int
551 ata_pcichannel_probe(device_t dev)
552 {
553     struct ata_channel *ch = device_get_softc(dev);
554     device_t *children;
555     int count, i;
556     char buffer[32];
557 
558     /* take care of green memory */
559     bzero(ch, sizeof(struct ata_channel));
560 
561     /* find channel number on this controller */
562     device_get_children(device_get_parent(dev), &children, &count);
563     for (i = 0; i < count; i++) {
564 	if (children[i] == dev)
565 	    ch->unit = i;
566     }
567     kfree(children, M_TEMP);
568 
569     ksprintf(buffer, "ATA channel %d", ch->unit);
570     device_set_desc_copy(dev, buffer);
571 
572     return ata_probe(dev);
573 }
574 
575 static int
576 ata_pcichannel_attach(device_t dev)
577 {
578     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
579     struct ata_channel *ch = device_get_softc(dev);
580     int error;
581 
582     if (ctlr->dmainit)
583 	ctlr->dmainit(dev);
584     if (ch->dma)
585 	ch->dma->alloc(dev);
586 
587     if ((error = ctlr->allocate(dev))) {
588 	if (ch->dma)
589 	    ch->dma->free(dev);
590 	return error;
591     }
592 
593     return ata_attach(dev);
594 }
595 
596 static int
597 ata_pcichannel_detach(device_t dev)
598 {
599     struct ata_channel *ch = device_get_softc(dev);
600     int error;
601 
602     if ((error = ata_detach(dev)))
603 	return error;
604 
605     if (ch->dma)
606 	ch->dma->free(dev);
607 
608     /* XXX SOS free resources for io and ctlio ?? */
609 
610     return 0;
611 }
612 
613 static int
614 ata_pcichannel_locking(device_t dev, int mode)
615 {
616     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
617     struct ata_channel *ch = device_get_softc(dev);
618 
619     if (ctlr->locking)
620 	return ctlr->locking(dev, mode);
621     else
622 	return ch->unit;
623 }
624 
625 static void
626 ata_pcichannel_reset(device_t dev)
627 {
628     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
629     struct ata_channel *ch = device_get_softc(dev);
630 
631     /* if DMA engine present reset it  */
632     if (ch->dma) {
633 	if (ch->dma->reset)
634 	    ch->dma->reset(dev);
635 	ch->dma->unload(dev);
636     }
637 
638     /* reset the controller HW */
639     if (ctlr->reset)
640 	ctlr->reset(dev);
641     else
642 	ata_generic_reset(dev);
643 }
644 
645 static void
646 ata_pcichannel_setmode(device_t parent, device_t dev)
647 {
648     struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev));
649     struct ata_device *atadev = device_get_softc(dev);
650     int mode = atadev->mode;
651 
652     ctlr->setmode(dev, ATA_PIO_MAX);
653     if (mode >= ATA_DMA)
654 	ctlr->setmode(dev, mode);
655 }
656 
657 static device_method_t ata_pcichannel_methods[] = {
658     /* device interface */
659     DEVMETHOD(device_probe,     ata_pcichannel_probe),
660     DEVMETHOD(device_attach,    ata_pcichannel_attach),
661     DEVMETHOD(device_detach,    ata_pcichannel_detach),
662     DEVMETHOD(device_shutdown,  bus_generic_shutdown),
663     DEVMETHOD(device_suspend,   ata_suspend),
664     DEVMETHOD(device_resume,    ata_resume),
665 
666     /* ATA methods */
667     DEVMETHOD(ata_setmode,      ata_pcichannel_setmode),
668     DEVMETHOD(ata_locking,      ata_pcichannel_locking),
669     DEVMETHOD(ata_reset,        ata_pcichannel_reset),
670 
671     { 0, 0 }
672 };
673 
674 driver_t ata_pcichannel_driver = {
675     "ata",
676     ata_pcichannel_methods,
677     sizeof(struct ata_channel),
678 };
679 
680 DRIVER_MODULE(ata, atapci, ata_pcichannel_driver, ata_devclass, 0, 0);
681