xref: /freebsd/sys/dev/ata/ata-sata.c (revision 6a5d28b9)
113014ca0SSøren Schmidt /*-
213014ca0SSøren Schmidt  * Copyright (c) 1998 - 2008 S�ren Schmidt <sos@FreeBSD.org>
313014ca0SSøren Schmidt  * All rights reserved.
413014ca0SSøren Schmidt  *
513014ca0SSøren Schmidt  * Redistribution and use in source and binary forms, with or without
613014ca0SSøren Schmidt  * modification, are permitted provided that the following conditions
713014ca0SSøren Schmidt  * are met:
813014ca0SSøren Schmidt  * 1. Redistributions of source code must retain the above copyright
913014ca0SSøren Schmidt  *    notice, this list of conditions and the following disclaimer,
1013014ca0SSøren Schmidt  *    without modification, immediately at the beginning of the file.
1113014ca0SSøren Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
1213014ca0SSøren Schmidt  *    notice, this list of conditions and the following disclaimer in the
1313014ca0SSøren Schmidt  *    documentation and/or other materials provided with the distribution.
1413014ca0SSøren Schmidt  *
1513014ca0SSøren Schmidt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1613014ca0SSøren Schmidt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1713014ca0SSøren Schmidt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1813014ca0SSøren Schmidt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1913014ca0SSøren Schmidt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2013014ca0SSøren Schmidt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2113014ca0SSøren Schmidt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2213014ca0SSøren Schmidt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2313014ca0SSøren Schmidt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2413014ca0SSøren Schmidt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2513014ca0SSøren Schmidt  */
2613014ca0SSøren Schmidt 
2713014ca0SSøren Schmidt #include <sys/cdefs.h>
2813014ca0SSøren Schmidt __FBSDID("$FreeBSD$");
2913014ca0SSøren Schmidt 
3013014ca0SSøren Schmidt #include "opt_ata.h"
3113014ca0SSøren Schmidt #include <sys/param.h>
3213014ca0SSøren Schmidt #include <sys/systm.h>
3313014ca0SSøren Schmidt #include <sys/kernel.h>
3413014ca0SSøren Schmidt #include <sys/ata.h>
3513014ca0SSøren Schmidt #include <sys/bus.h>
3613014ca0SSøren Schmidt #include <sys/endian.h>
3713014ca0SSøren Schmidt #include <sys/malloc.h>
3813014ca0SSøren Schmidt #include <sys/lock.h>
3913014ca0SSøren Schmidt #include <sys/mutex.h>
4013014ca0SSøren Schmidt #include <sys/sema.h>
4113014ca0SSøren Schmidt #include <sys/taskqueue.h>
4213014ca0SSøren Schmidt #include <vm/uma.h>
4313014ca0SSøren Schmidt #include <machine/stdarg.h>
4413014ca0SSøren Schmidt #include <machine/resource.h>
4513014ca0SSøren Schmidt #include <machine/bus.h>
4613014ca0SSøren Schmidt #include <sys/rman.h>
4713014ca0SSøren Schmidt #include <dev/ata/ata-all.h>
4813014ca0SSøren Schmidt #include <ata_if.h>
4913014ca0SSøren Schmidt 
5013014ca0SSøren Schmidt void
5113014ca0SSøren Schmidt ata_sata_phy_check_events(device_t dev)
5213014ca0SSøren Schmidt {
5313014ca0SSøren Schmidt     struct ata_channel *ch = device_get_softc(dev);
5413014ca0SSøren Schmidt     u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR);
5513014ca0SSøren Schmidt 
5613014ca0SSøren Schmidt     /* clear error bits/interrupt */
5713014ca0SSøren Schmidt     ATA_IDX_OUTL(ch, ATA_SERROR, error);
5813014ca0SSøren Schmidt 
5913014ca0SSøren Schmidt     /* if we have a connection event deal with it */
604c10f2e6SAlexander Motin     if ((error & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) {
616030a3f0SAlexander Motin 	if (bootverbose) {
626030a3f0SAlexander Motin 	    u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS);
6313014ca0SSøren Schmidt 	    if (((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1) ||
6413014ca0SSøren Schmidt 		((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)) {
6513014ca0SSøren Schmidt 		    device_printf(dev, "CONNECT requested\n");
666030a3f0SAlexander Motin 	    } else
6713014ca0SSøren Schmidt 		    device_printf(dev, "DISCONNECT requested\n");
6813014ca0SSøren Schmidt 	}
696030a3f0SAlexander Motin 	taskqueue_enqueue(taskqueue_thread, &ch->conntask);
7013014ca0SSøren Schmidt     }
7113014ca0SSøren Schmidt }
7213014ca0SSøren Schmidt 
739cf4fe2eSAlexander Motin int
749cf4fe2eSAlexander Motin ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val)
759cf4fe2eSAlexander Motin {
769cf4fe2eSAlexander Motin     int r;
779cf4fe2eSAlexander Motin 
789cf4fe2eSAlexander Motin     if (port < 0) {
799cf4fe2eSAlexander Motin 	*val = ATA_IDX_INL(ch, reg);
809cf4fe2eSAlexander Motin 	return (0);
819cf4fe2eSAlexander Motin     } else {
829cf4fe2eSAlexander Motin 	switch (reg) {
839cf4fe2eSAlexander Motin 	    case ATA_SSTATUS:
849cf4fe2eSAlexander Motin 		r = 0;
859cf4fe2eSAlexander Motin 		break;
869cf4fe2eSAlexander Motin 	    case ATA_SERROR:
879cf4fe2eSAlexander Motin 		r = 1;
889cf4fe2eSAlexander Motin 		break;
899cf4fe2eSAlexander Motin 	    case ATA_SCONTROL:
909cf4fe2eSAlexander Motin 		r = 2;
919cf4fe2eSAlexander Motin 		break;
929cf4fe2eSAlexander Motin 	    default:
939cf4fe2eSAlexander Motin 		return (EINVAL);
949cf4fe2eSAlexander Motin 	}
959cf4fe2eSAlexander Motin 	return (ch->hw.pm_read(ch->dev, port, r, val));
969cf4fe2eSAlexander Motin     }
979cf4fe2eSAlexander Motin }
989cf4fe2eSAlexander Motin 
999cf4fe2eSAlexander Motin int
1009cf4fe2eSAlexander Motin ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val)
1019cf4fe2eSAlexander Motin {
1029cf4fe2eSAlexander Motin     int r;
1039cf4fe2eSAlexander Motin 
1049cf4fe2eSAlexander Motin     if (port < 0) {
1059cf4fe2eSAlexander Motin 	ATA_IDX_OUTL(ch, reg, val);
1069cf4fe2eSAlexander Motin 	return (0);
1079cf4fe2eSAlexander Motin     } else {
1089cf4fe2eSAlexander Motin 	switch (reg) {
1099cf4fe2eSAlexander Motin 	    case ATA_SERROR:
1109cf4fe2eSAlexander Motin 		r = 1;
1119cf4fe2eSAlexander Motin 		break;
1129cf4fe2eSAlexander Motin 	    case ATA_SCONTROL:
1139cf4fe2eSAlexander Motin 		r = 2;
1149cf4fe2eSAlexander Motin 		break;
1159cf4fe2eSAlexander Motin 	    default:
1169cf4fe2eSAlexander Motin 		return (EINVAL);
1179cf4fe2eSAlexander Motin 	}
1189cf4fe2eSAlexander Motin 	return (ch->hw.pm_write(ch->dev, port, r, val));
1199cf4fe2eSAlexander Motin     }
1209cf4fe2eSAlexander Motin }
1219cf4fe2eSAlexander Motin 
12213014ca0SSøren Schmidt static int
1239cf4fe2eSAlexander Motin ata_sata_connect(struct ata_channel *ch, int port)
12413014ca0SSøren Schmidt {
12513014ca0SSøren Schmidt     u_int32_t status;
12613014ca0SSøren Schmidt     int timeout;
12713014ca0SSøren Schmidt 
12813014ca0SSøren Schmidt     /* wait up to 1 second for "connect well" */
12913014ca0SSøren Schmidt     for (timeout = 0; timeout < 100 ; timeout++) {
1309cf4fe2eSAlexander Motin 	if (ata_sata_scr_read(ch, port, ATA_SSTATUS, &status))
1319cf4fe2eSAlexander Motin 	    return (0);
13213014ca0SSøren Schmidt 	if ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1 ||
13313014ca0SSøren Schmidt 	    (status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)
13413014ca0SSøren Schmidt 	    break;
13513014ca0SSøren Schmidt 	ata_udelay(10000);
13613014ca0SSøren Schmidt     }
13713014ca0SSøren Schmidt     if (timeout >= 100) {
1389cf4fe2eSAlexander Motin 	if (bootverbose) {
1399cf4fe2eSAlexander Motin 	    if (port < 0) {
1409cf4fe2eSAlexander Motin 		device_printf(ch->dev, "SATA connect timeout status=%08x\n",
1419cf4fe2eSAlexander Motin 		    status);
1429cf4fe2eSAlexander Motin 	    } else {
1439cf4fe2eSAlexander Motin 		device_printf(ch->dev, "p%d: SATA connect timeout status=%08x\n",
1449cf4fe2eSAlexander Motin 		    port, status);
1459cf4fe2eSAlexander Motin 	    }
1469cf4fe2eSAlexander Motin 	}
14713014ca0SSøren Schmidt 	return 0;
14813014ca0SSøren Schmidt     }
1499cf4fe2eSAlexander Motin     if (bootverbose) {
1509cf4fe2eSAlexander Motin 	if (port < 0) {
1519cf4fe2eSAlexander Motin 	    device_printf(ch->dev, "SATA connect time=%dms status=%08x\n",
1529cf4fe2eSAlexander Motin 		timeout * 10, status);
1539cf4fe2eSAlexander Motin 	} else {
1549cf4fe2eSAlexander Motin 	    device_printf(ch->dev, "p%d: SATA connect time=%dms status=%08x\n",
1559cf4fe2eSAlexander Motin 		port, timeout * 10, status);
1569cf4fe2eSAlexander Motin 	}
1579cf4fe2eSAlexander Motin     }
15813014ca0SSøren Schmidt 
15913014ca0SSøren Schmidt     /* clear SATA error register */
1609cf4fe2eSAlexander Motin     ata_sata_scr_write(ch, port, ATA_SERROR, 0xffffffff);
16113014ca0SSøren Schmidt 
16213014ca0SSøren Schmidt     return 1;
16313014ca0SSøren Schmidt }
16413014ca0SSøren Schmidt 
16513014ca0SSøren Schmidt int
1669cf4fe2eSAlexander Motin ata_sata_phy_reset(device_t dev, int port, int quick)
16713014ca0SSøren Schmidt {
16813014ca0SSøren Schmidt     struct ata_channel *ch = device_get_softc(dev);
16913014ca0SSøren Schmidt     int loop, retry;
1709cf4fe2eSAlexander Motin     uint32_t val;
17113014ca0SSøren Schmidt 
1729cf4fe2eSAlexander Motin     if (quick) {
1739cf4fe2eSAlexander Motin 	if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
1749cf4fe2eSAlexander Motin 	    return (0);
1759cf4fe2eSAlexander Motin 	if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
1769cf4fe2eSAlexander Motin 	    return ata_sata_connect(ch, port);
1779cf4fe2eSAlexander Motin     }
17813014ca0SSøren Schmidt 
1799cf4fe2eSAlexander Motin     if (bootverbose) {
1809cf4fe2eSAlexander Motin 	if (port < 0) {
1819cf4fe2eSAlexander Motin 	    device_printf(dev, "hardware reset ...\n");
1829cf4fe2eSAlexander Motin 	} else {
1839cf4fe2eSAlexander Motin 	    device_printf(dev, "p%d: hardware reset ...\n", port);
1849cf4fe2eSAlexander Motin 	}
1859cf4fe2eSAlexander Motin     }
18613014ca0SSøren Schmidt     for (retry = 0; retry < 10; retry++) {
18713014ca0SSøren Schmidt 	for (loop = 0; loop < 10; loop++) {
1889cf4fe2eSAlexander Motin 	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL, ATA_SC_DET_RESET))
1899cf4fe2eSAlexander Motin 		return (0);
19013014ca0SSøren Schmidt 	    ata_udelay(100);
1919cf4fe2eSAlexander Motin 	    if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
1929cf4fe2eSAlexander Motin 		return (0);
1939cf4fe2eSAlexander Motin 	    if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_RESET)
19413014ca0SSøren Schmidt 		break;
19513014ca0SSøren Schmidt 	}
19613014ca0SSøren Schmidt 	ata_udelay(5000);
19713014ca0SSøren Schmidt 	for (loop = 0; loop < 10; loop++) {
1989cf4fe2eSAlexander Motin 	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL,
1994c10f2e6SAlexander Motin 		    ATA_SC_DET_IDLE | ((ch->pm_level > 0) ? 0 :
2004c10f2e6SAlexander Motin 		    ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)))
2019cf4fe2eSAlexander Motin 		return (0);
20213014ca0SSøren Schmidt 	    ata_udelay(100);
2039cf4fe2eSAlexander Motin 	    if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
2049cf4fe2eSAlexander Motin 		return (0);
2059cf4fe2eSAlexander Motin 	    if ((val & ATA_SC_DET_MASK) == 0)
2069cf4fe2eSAlexander Motin 		return ata_sata_connect(ch, port);
20713014ca0SSøren Schmidt 	}
20813014ca0SSøren Schmidt     }
20913014ca0SSøren Schmidt     return 0;
21013014ca0SSøren Schmidt }
21113014ca0SSøren Schmidt 
212066f913aSAlexander Motin int
213066f913aSAlexander Motin ata_sata_setmode(device_t dev, int target, int mode)
21413014ca0SSøren Schmidt {
21513014ca0SSøren Schmidt 
216066f913aSAlexander Motin 	return (min(mode, ATA_UDMA5));
21713014ca0SSøren Schmidt }
218066f913aSAlexander Motin 
219066f913aSAlexander Motin int
220066f913aSAlexander Motin ata_sata_getrev(device_t dev, int target)
221066f913aSAlexander Motin {
222066f913aSAlexander Motin 	struct ata_channel *ch = device_get_softc(dev);
223066f913aSAlexander Motin 
224066f913aSAlexander Motin 	if (ch->r_io[ATA_SSTATUS].res)
225066f913aSAlexander Motin 		return ((ATA_IDX_INL(ch, ATA_SSTATUS) & 0x0f0) >> 4);
2266a5d28b9SAlexander Motin 	return (0xff);
22713014ca0SSøren Schmidt }
22813014ca0SSøren Schmidt 
22913014ca0SSøren Schmidt int
23013014ca0SSøren Schmidt ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis)
23113014ca0SSøren Schmidt {
23213014ca0SSøren Schmidt 
23313014ca0SSøren Schmidt     if (request->flags & ATA_R_ATAPI) {
23413014ca0SSøren Schmidt 	fis[0] = 0x27;  		/* host to device */
235ebbb35baSAlexander Motin 	fis[1] = 0x80 | (request->unit & 0x0f);
23613014ca0SSøren Schmidt 	fis[2] = ATA_PACKET_CMD;
23713014ca0SSøren Schmidt 	if (request->flags & (ATA_R_READ | ATA_R_WRITE))
23813014ca0SSøren Schmidt 	    fis[3] = ATA_F_DMA;
23913014ca0SSøren Schmidt 	else {
24013014ca0SSøren Schmidt 	    fis[5] = request->transfersize;
24113014ca0SSøren Schmidt 	    fis[6] = request->transfersize >> 8;
24213014ca0SSøren Schmidt 	}
24313014ca0SSøren Schmidt 	fis[7] = ATA_D_LBA;
24413014ca0SSøren Schmidt 	fis[15] = ATA_A_4BIT;
24513014ca0SSøren Schmidt 	return 20;
24613014ca0SSøren Schmidt     }
24713014ca0SSøren Schmidt     else {
24813014ca0SSøren Schmidt 	fis[0] = 0x27;			/* host to device */
249ebbb35baSAlexander Motin 	fis[1] = 0x80 | (request->unit & 0x0f);
25013014ca0SSøren Schmidt 	fis[2] = request->u.ata.command;
25113014ca0SSøren Schmidt 	fis[3] = request->u.ata.feature;
25213014ca0SSøren Schmidt 	fis[4] = request->u.ata.lba;
25313014ca0SSøren Schmidt 	fis[5] = request->u.ata.lba >> 8;
25413014ca0SSøren Schmidt 	fis[6] = request->u.ata.lba >> 16;
25513014ca0SSøren Schmidt 	fis[7] = ATA_D_LBA;
256ebbb35baSAlexander Motin 	if (!(request->flags & ATA_R_48BIT))
25713014ca0SSøren Schmidt 	    fis[7] |= (ATA_D_IBM | (request->u.ata.lba >> 24 & 0x0f));
25813014ca0SSøren Schmidt 	fis[8] = request->u.ata.lba >> 24;
25913014ca0SSøren Schmidt 	fis[9] = request->u.ata.lba >> 32;
26013014ca0SSøren Schmidt 	fis[10] = request->u.ata.lba >> 40;
26113014ca0SSøren Schmidt 	fis[11] = request->u.ata.feature >> 8;
26213014ca0SSøren Schmidt 	fis[12] = request->u.ata.count;
26313014ca0SSøren Schmidt 	fis[13] = request->u.ata.count >> 8;
26413014ca0SSøren Schmidt 	fis[15] = ATA_A_4BIT;
26513014ca0SSøren Schmidt 	return 20;
26613014ca0SSøren Schmidt     }
26713014ca0SSøren Schmidt     return 0;
26813014ca0SSøren Schmidt }
26913014ca0SSøren Schmidt 
27013014ca0SSøren Schmidt void
27113014ca0SSøren Schmidt ata_pm_identify(device_t dev)
27213014ca0SSøren Schmidt {
27313014ca0SSøren Schmidt     struct ata_channel *ch = device_get_softc(dev);
27413014ca0SSøren Schmidt     u_int32_t pm_chipid, pm_revision, pm_ports;
27513014ca0SSøren Schmidt     int port;
27613014ca0SSøren Schmidt 
27713014ca0SSøren Schmidt     /* get PM vendor & product data */
27813014ca0SSøren Schmidt     if (ch->hw.pm_read(dev, ATA_PM, 0, &pm_chipid)) {
27913014ca0SSøren Schmidt 	device_printf(dev, "error getting PM vendor data\n");
28013014ca0SSøren Schmidt 	return;
28113014ca0SSøren Schmidt     }
28213014ca0SSøren Schmidt 
28313014ca0SSøren Schmidt     /* get PM revision data */
28413014ca0SSøren Schmidt     if (ch->hw.pm_read(dev, ATA_PM, 1, &pm_revision)) {
28513014ca0SSøren Schmidt 	device_printf(dev, "error getting PM revison data\n");
28613014ca0SSøren Schmidt 	return;
28713014ca0SSøren Schmidt     }
28813014ca0SSøren Schmidt 
28913014ca0SSøren Schmidt     /* get number of HW ports on the PM */
29013014ca0SSøren Schmidt     if (ch->hw.pm_read(dev, ATA_PM, 2, &pm_ports)) {
29113014ca0SSøren Schmidt 	device_printf(dev, "error getting PM port info\n");
29213014ca0SSøren Schmidt 	return;
29313014ca0SSøren Schmidt     }
29413014ca0SSøren Schmidt     pm_ports &= 0x0000000f;
29513014ca0SSøren Schmidt 
29613014ca0SSøren Schmidt     /* chip specific quirks */
29713014ca0SSøren Schmidt     switch (pm_chipid) {
29813014ca0SSøren Schmidt     case 0x37261095:
2999cf4fe2eSAlexander Motin 	/* This PM declares 6 ports, while only 5 of them are real.
3009cf4fe2eSAlexander Motin 	 * Port 5 is enclosure management bridge port, which has implementation
3019cf4fe2eSAlexander Motin 	 * problems, causing probe faults. Hide it for now. */
3029cf4fe2eSAlexander Motin 	device_printf(dev, "SiI 3726 (rev=%x) Port Multiplier with %d (5) ports\n",
30313014ca0SSøren Schmidt 		      pm_revision, pm_ports);
3049cf4fe2eSAlexander Motin 	pm_ports = 5;
3059cf4fe2eSAlexander Motin 	break;
3069cf4fe2eSAlexander Motin 
3079cf4fe2eSAlexander Motin     case 0x47261095:
3089cf4fe2eSAlexander Motin 	/* This PM declares 7 ports, while only 5 of them are real.
3099cf4fe2eSAlexander Motin 	 * Port 5 is some fake "Config  Disk" with 640 sectors size,
3109cf4fe2eSAlexander Motin 	 * port 6 is enclosure management bridge port.
3119cf4fe2eSAlexander Motin 	 * Both fake ports has implementation problems, causing
3129cf4fe2eSAlexander Motin 	 * probe faults. Hide them for now. */
3139cf4fe2eSAlexander Motin 	device_printf(dev, "SiI 4726 (rev=%x) Port Multiplier with %d (5) ports\n",
3149cf4fe2eSAlexander Motin 		      pm_revision, pm_ports);
3159cf4fe2eSAlexander Motin 	pm_ports = 5;
31613014ca0SSøren Schmidt 	break;
31713014ca0SSøren Schmidt 
31813014ca0SSøren Schmidt     default:
3199cf4fe2eSAlexander Motin 	device_printf(dev, "Port Multiplier (id=%08x rev=%x) with %d ports\n",
32013014ca0SSøren Schmidt 		      pm_chipid, pm_revision, pm_ports);
32113014ca0SSøren Schmidt     }
32213014ca0SSøren Schmidt 
32313014ca0SSøren Schmidt     /* reset all ports and register if anything connected */
32413014ca0SSøren Schmidt     for (port=0; port < pm_ports; port++) {
3259cf4fe2eSAlexander Motin 	u_int32_t signature;
32613014ca0SSøren Schmidt 
3279cf4fe2eSAlexander Motin 	if (!ata_sata_phy_reset(dev, port, 1))
32813014ca0SSøren Schmidt 	    continue;
32913014ca0SSøren Schmidt 
3309cf4fe2eSAlexander Motin 	/*
3319cf4fe2eSAlexander Motin 	 * XXX: I have no idea how to properly wait for PMP port hardreset
3329cf4fe2eSAlexander Motin 	 * completion. Without this delay soft reset does not completes
3339cf4fe2eSAlexander Motin 	 * successfully.
3349cf4fe2eSAlexander Motin 	 */
3359cf4fe2eSAlexander Motin 	DELAY(1000000);
33613014ca0SSøren Schmidt 
33713014ca0SSøren Schmidt 	signature = ch->hw.softreset(dev, port);
33813014ca0SSøren Schmidt 
33913014ca0SSøren Schmidt 	if (bootverbose)
34013014ca0SSøren Schmidt 	    device_printf(dev, "p%d: SIGNATURE=%08x\n", port, signature);
34113014ca0SSøren Schmidt 
34213014ca0SSøren Schmidt 	/* figure out whats there */
343e412a8c3SAlexander Motin 	switch (signature >> 16) {
344e412a8c3SAlexander Motin 	case 0x0000:
34513014ca0SSøren Schmidt 	    ch->devices |= (ATA_ATA_MASTER << port);
34613014ca0SSøren Schmidt 	    continue;
347e412a8c3SAlexander Motin 	case 0xeb14:
34813014ca0SSøren Schmidt 	    ch->devices |= (ATA_ATAPI_MASTER << port);
34913014ca0SSøren Schmidt 	    continue;
35013014ca0SSøren Schmidt 	}
35113014ca0SSøren Schmidt     }
35213014ca0SSøren Schmidt }
353