xref: /freebsd/sys/dev/ata/ata-sata.c (revision 54ebdd631db8c0bba2baab0155f603a8b5cf014a)
1 /*-
2  * Copyright (c) 1998 - 2008 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 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include "opt_ata.h"
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/ata.h>
35 #include <sys/bus.h>
36 #include <sys/endian.h>
37 #include <sys/malloc.h>
38 #include <sys/lock.h>
39 #include <sys/mutex.h>
40 #include <sys/sema.h>
41 #include <sys/taskqueue.h>
42 #include <vm/uma.h>
43 #include <machine/stdarg.h>
44 #include <machine/resource.h>
45 #include <machine/bus.h>
46 #include <sys/rman.h>
47 #include <dev/pci/pcivar.h>
48 #include <dev/pci/pcireg.h>
49 #include <dev/ata/ata-all.h>
50 #include <dev/ata/ata-pci.h>
51 #include <ata_if.h>
52 
53 /*
54  * SATA support functions
55  */
56 void
57 ata_sata_phy_event(void *context, int dummy)
58 {
59     struct ata_connect_task *tp = (struct ata_connect_task *)context;
60     struct ata_channel *ch = device_get_softc(tp->dev);
61     device_t *children;
62     int nchildren, i;
63 
64     mtx_lock(&Giant);   /* newbus suckage it needs Giant */
65     if (tp->action == ATA_C_ATTACH) {
66 	if (bootverbose)
67 	    device_printf(tp->dev, "CONNECTED\n");
68 	ATA_RESET(tp->dev);
69 	ata_identify(tp->dev);
70     }
71     if (tp->action == ATA_C_DETACH) {
72 	if (!device_get_children(tp->dev, &children, &nchildren)) {
73 	    for (i = 0; i < nchildren; i++)
74 		if (children[i])
75 		    device_delete_child(tp->dev, children[i]);
76 	    free(children, M_TEMP);
77 	}
78 	mtx_lock(&ch->state_mtx);
79 	ch->state = ATA_IDLE;
80 	mtx_unlock(&ch->state_mtx);
81 	if (bootverbose)
82 	    device_printf(tp->dev, "DISCONNECTED\n");
83     }
84     mtx_unlock(&Giant); /* suckage code dealt with, release Giant */
85     free(tp, M_ATA);
86 }
87 
88 void
89 ata_sata_phy_check_events(device_t dev)
90 {
91     struct ata_channel *ch = device_get_softc(dev);
92     u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR);
93 
94     /* clear error bits/interrupt */
95     ATA_IDX_OUTL(ch, ATA_SERROR, error);
96 
97     /* do we have any events flagged ? */
98     if (error) {
99 	struct ata_connect_task *tp;
100 	u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS);
101 
102 	/* if we have a connection event deal with it */
103 	if ((error & ATA_SE_PHY_CHANGED) &&
104 	    (tp = (struct ata_connect_task *)
105 		  malloc(sizeof(struct ata_connect_task),
106 			 M_ATA, M_NOWAIT | M_ZERO))) {
107 
108 	    if (((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1) ||
109 		((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)) {
110 		if (bootverbose)
111 		    device_printf(dev, "CONNECT requested\n");
112 		tp->action = ATA_C_ATTACH;
113 	    }
114 	    else {
115 		if (bootverbose)
116 		    device_printf(dev, "DISCONNECT requested\n");
117 		tp->action = ATA_C_DETACH;
118 	    }
119 	    tp->dev = dev;
120 	    TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp);
121 	    taskqueue_enqueue(taskqueue_thread, &tp->task);
122 	}
123     }
124 }
125 
126 static int
127 ata_sata_connect(struct ata_channel *ch)
128 {
129     u_int32_t status;
130     int timeout;
131 
132     /* wait up to 1 second for "connect well" */
133     for (timeout = 0; timeout < 100 ; timeout++) {
134 	status = ATA_IDX_INL(ch, ATA_SSTATUS);
135 	if ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1 ||
136 	    (status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)
137 	    break;
138 	ata_udelay(10000);
139     }
140     if (timeout >= 100) {
141 	if (bootverbose)
142 	    device_printf(ch->dev, "SATA connect status=%08x\n", status);
143 	return 0;
144     }
145     if (bootverbose)
146 	device_printf(ch->dev, "SATA connect time=%dms\n", timeout * 10);
147 
148     /* clear SATA error register */
149     ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR));
150 
151     return 1;
152 }
153 
154 int
155 ata_sata_phy_reset(device_t dev)
156 {
157     struct ata_channel *ch = device_get_softc(dev);
158     int loop, retry;
159 
160     if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
161 	return ata_sata_connect(ch);
162 
163     for (retry = 0; retry < 10; retry++) {
164 	for (loop = 0; loop < 10; loop++) {
165 	    ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_RESET);
166 	    ata_udelay(100);
167 	    if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) ==
168 		ATA_SC_DET_RESET)
169 		break;
170 	}
171 	ata_udelay(5000);
172 	for (loop = 0; loop < 10; loop++) {
173 	    ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_IDLE |
174 					   ATA_SC_IPM_DIS_PARTIAL |
175 					   ATA_SC_IPM_DIS_SLUMBER);
176 	    ata_udelay(100);
177 	    if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == 0)
178 		return ata_sata_connect(ch);
179 	}
180     }
181     return 0;
182 }
183 
184 void
185 ata_sata_setmode(device_t dev, int mode)
186 {
187     struct ata_device *atadev = device_get_softc(dev);
188 
189     /*
190      * if we detect that the device isn't a real SATA device we limit
191      * the transfer mode to UDMA5/ATA100.
192      * this works around the problems some devices has with the
193      * Marvell 88SX8030 SATA->PATA converters and UDMA6/ATA133.
194      */
195     if (atadev->param.satacapabilities != 0x0000 &&
196 	atadev->param.satacapabilities != 0xffff) {
197 	struct ata_channel *ch = device_get_softc(device_get_parent(dev));
198 
199 	/* on some drives we need to set the transfer mode */
200 	ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
201 		       ata_limit_mode(dev, mode, ATA_UDMA6));
202 
203 	/* query SATA STATUS for the speed */
204         if (ch->r_io[ATA_SSTATUS].res &&
205 	   ((ATA_IDX_INL(ch, ATA_SSTATUS) & ATA_SS_CONWELL_MASK) ==
206 	    ATA_SS_CONWELL_GEN2))
207 	    atadev->mode = ATA_SA300;
208 	else
209 	    atadev->mode = ATA_SA150;
210     }
211     else {
212 	mode = ata_limit_mode(dev, mode, ATA_UDMA5);
213 	if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
214 	    atadev->mode = mode;
215     }
216 }
217 
218 int
219 ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis)
220 {
221     struct ata_device *atadev = device_get_softc(request->dev);
222 
223     if (request->flags & ATA_R_ATAPI) {
224 	fis[0] = 0x27;  		/* host to device */
225 	fis[1] = 0x80 | (atadev->unit & 0x0f);
226 	fis[2] = ATA_PACKET_CMD;
227 	if (request->flags & (ATA_R_READ | ATA_R_WRITE))
228 	    fis[3] = ATA_F_DMA;
229 	else {
230 	    fis[5] = request->transfersize;
231 	    fis[6] = request->transfersize >> 8;
232 	}
233 	fis[7] = ATA_D_LBA;
234 	fis[15] = ATA_A_4BIT;
235 	return 20;
236     }
237     else {
238 	ata_modify_if_48bit(request);
239 	fis[0] = 0x27;			/* host to device */
240 	fis[1] = 0x80 | (atadev->unit & 0x0f);
241 	fis[2] = request->u.ata.command;
242 	fis[3] = request->u.ata.feature;
243 	fis[4] = request->u.ata.lba;
244 	fis[5] = request->u.ata.lba >> 8;
245 	fis[6] = request->u.ata.lba >> 16;
246 	fis[7] = ATA_D_LBA;
247 	if (!(atadev->flags & ATA_D_48BIT_ACTIVE))
248 	    fis[7] |= (ATA_D_IBM | (request->u.ata.lba >> 24 & 0x0f));
249 	fis[8] = request->u.ata.lba >> 24;
250 	fis[9] = request->u.ata.lba >> 32;
251 	fis[10] = request->u.ata.lba >> 40;
252 	fis[11] = request->u.ata.feature >> 8;
253 	fis[12] = request->u.ata.count;
254 	fis[13] = request->u.ata.count >> 8;
255 	fis[15] = ATA_A_4BIT;
256 	return 20;
257     }
258     return 0;
259 }
260 
261 void
262 ata_pm_identify(device_t dev)
263 {
264     struct ata_channel *ch = device_get_softc(dev);
265     u_int32_t pm_chipid, pm_revision, pm_ports;
266     int port;
267 
268     /* get PM vendor & product data */
269     if (ch->hw.pm_read(dev, ATA_PM, 0, &pm_chipid)) {
270 	device_printf(dev, "error getting PM vendor data\n");
271 	return;
272     }
273 
274     /* get PM revision data */
275     if (ch->hw.pm_read(dev, ATA_PM, 1, &pm_revision)) {
276 	device_printf(dev, "error getting PM revison data\n");
277 	return;
278     }
279 
280     /* get number of HW ports on the PM */
281     if (ch->hw.pm_read(dev, ATA_PM, 2, &pm_ports)) {
282 	device_printf(dev, "error getting PM port info\n");
283 	return;
284     }
285     pm_ports &= 0x0000000f;
286 
287     /* chip specific quirks */
288     switch (pm_chipid) {
289     case 0x37261095:
290 	/* Some of these bogusly reports 6 ports */
291 	pm_ports = 5;
292 	device_printf(dev, "SiI 3726 r%x Portmultiplier with %d ports\n",
293 		      pm_revision, pm_ports);
294 	break;
295 
296     default:
297 	device_printf(dev, "Portmultiplier (id=%08x rev=%x) with %d ports\n",
298 		      pm_chipid, pm_revision, pm_ports);
299     }
300 
301     /* realloc space for needed DMA slots */
302     ch->dma.dma_slots = pm_ports;
303 
304     /* reset all ports and register if anything connected */
305     for (port=0; port < pm_ports; port++) {
306 	u_int32_t signature, status;
307 	int timeout;
308 
309 	if (ch->hw.pm_write(dev, port, 2, ATA_SC_DET_RESET)) {
310 	    device_printf(dev, "p%d: writing ATA_SC_DET_RESET failed\n", port);
311 	    continue;
312 	}
313 
314 	ata_udelay(5000);
315 
316 	if (ch->hw.pm_write(dev, port, 2, ATA_SC_DET_IDLE)) {
317 	    device_printf(dev, "p%d: writing ATA_SC_DET_idle failed\n", port);
318 	    continue;
319 	}
320 
321 	ata_udelay(5000);
322 
323 	/* wait up to 1 second for "connect well" */
324 	for (timeout = 0; timeout < 100 ; timeout++) {
325 	    ch->hw.pm_read(dev, port, 0, &status);
326 	    if ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1 ||
327 		(status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)
328 		break;
329 	    ata_udelay(10000);
330 	}
331 	if (timeout >= 100) {
332 	    if (bootverbose)
333 		device_printf(dev, "p%d: connect status=%08x\n", port, status);
334 	    continue;
335 	}
336 	if (bootverbose)
337 	    device_printf(dev, "p%d: connect time %dms\n", port, timeout * 10);
338 
339 	/* clear SERROR register */
340 	ch->hw.pm_write(dev, port, 1, 0xffffffff);
341 
342 	signature = ch->hw.softreset(dev, port);
343 
344 	if (bootverbose)
345 	    device_printf(dev, "p%d: SIGNATURE=%08x\n", port, signature);
346 
347 	/* figure out whats there */
348 	switch (signature) {
349 	case 0x00000101:
350 	    ch->devices |= (ATA_ATA_MASTER << port);
351 	    continue;
352 	case 0xeb140101:
353 	    ch->devices |= (ATA_ATAPI_MASTER << port);
354 	    continue;
355 	}
356     }
357 }
358