]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ata/ata-sata.c
add -n option to suppress clearing the build tree and add -DNO_CLEAN
[FreeBSD/FreeBSD.git] / sys / dev / ata / ata-sata.c
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 }