Wed Oct 1 18:23:55 2008 UTC ()
Use a separate thread to probe/attach atabus's childrens. Fixes a deadlock
where the interrupt routine wants to wake up the atabus thread to perform a
reset, while the thread is blocked in wd's attach function.


(bouyer)
diff -r1.99 -r1.100 src/sys/dev/ata/ata.c

cvs diff -r1.99 -r1.100 src/sys/dev/ata/ata.c (expand / switch to unified diff)

--- src/sys/dev/ata/ata.c 2008/06/12 21:46:35 1.99
+++ src/sys/dev/ata/ata.c 2008/10/01 18:23:55 1.100
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ata.c,v 1.99 2008/06/12 21:46:35 cegger Exp $ */ 1/* $NetBSD: ata.c,v 1.100 2008/10/01 18:23:55 bouyer Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. 4 * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software 14 * 3. All advertising materials mentioning features or use of this software
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.99 2008/06/12 21:46:35 cegger Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.100 2008/10/01 18:23:55 bouyer Exp $");
34 34
35#include "opt_ata.h" 35#include "opt_ata.h"
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/kernel.h> 39#include <sys/kernel.h>
40#include <sys/malloc.h> 40#include <sys/malloc.h>
41#include <sys/device.h> 41#include <sys/device.h>
42#include <sys/conf.h> 42#include <sys/conf.h>
43#include <sys/fcntl.h> 43#include <sys/fcntl.h>
44#include <sys/proc.h> 44#include <sys/proc.h>
45#include <sys/pool.h> 45#include <sys/pool.h>
46#include <sys/kthread.h> 46#include <sys/kthread.h>
@@ -79,47 +79,51 @@ int atadebug_mask = 0; @@ -79,47 +79,51 @@ int atadebug_mask = 0;
79#endif 79#endif
80 80
81POOL_INIT(ata_xfer_pool, sizeof(struct ata_xfer), 0, 0, 0, "ataspl", NULL, 81POOL_INIT(ata_xfer_pool, sizeof(struct ata_xfer), 0, 0, 0, "ataspl", NULL,
82 IPL_BIO); 82 IPL_BIO);
83 83
84/* 84/*
85 * A queue of atabus instances, used to ensure the same bus probe order 85 * A queue of atabus instances, used to ensure the same bus probe order
86 * for a given hardware configuration at each boot. 86 * for a given hardware configuration at each boot.
87 */ 87 */
88struct atabus_initq_head atabus_initq_head = 88struct atabus_initq_head atabus_initq_head =
89 TAILQ_HEAD_INITIALIZER(atabus_initq_head); 89 TAILQ_HEAD_INITIALIZER(atabus_initq_head);
90struct simplelock atabus_interlock = SIMPLELOCK_INITIALIZER; 90struct simplelock atabus_interlock = SIMPLELOCK_INITIALIZER;
91 91
 92/* kernel thread probing devices on a atabus. Only one probing at once */
 93struct lwp *atabus_configlwp;
 94
92/***************************************************************************** 95/*****************************************************************************
93 * ATA bus layer. 96 * ATA bus layer.
94 * 97 *
95 * ATA controllers attach an atabus instance, which handles probing the bus 98 * ATA controllers attach an atabus instance, which handles probing the bus
96 * for drives, etc. 99 * for drives, etc.
97 *****************************************************************************/ 100 *****************************************************************************/
98 101
99dev_type_open(atabusopen); 102dev_type_open(atabusopen);
100dev_type_close(atabusclose); 103dev_type_close(atabusclose);
101dev_type_ioctl(atabusioctl); 104dev_type_ioctl(atabusioctl);
102 105
103const struct cdevsw atabus_cdevsw = { 106const struct cdevsw atabus_cdevsw = {
104 atabusopen, atabusclose, noread, nowrite, atabusioctl, 107 atabusopen, atabusclose, noread, nowrite, atabusioctl,
105 nostop, notty, nopoll, nommap, nokqfilter, D_OTHER 108 nostop, notty, nopoll, nommap, nokqfilter, D_OTHER
106}; 109};
107 110
108extern struct cfdriver atabus_cd; 111extern struct cfdriver atabus_cd;
109 112
110static void atabus_childdetached(device_t, device_t); 113static void atabus_childdetached(device_t, device_t);
111static bool atabus_resume(device_t PMF_FN_PROTO); 114static bool atabus_resume(device_t PMF_FN_PROTO);
112static bool atabus_suspend(device_t PMF_FN_PROTO); 115static bool atabus_suspend(device_t PMF_FN_PROTO);
 116static void atabusconfig_thread(void *);
113 117
114/* 118/*
115 * atabusprint: 119 * atabusprint:
116 * 120 *
117 * Autoconfiguration print routine used by ATA controllers when 121 * Autoconfiguration print routine used by ATA controllers when
118 * attaching an atabus instance. 122 * attaching an atabus instance.
119 */ 123 */
120int 124int
121atabusprint(void *aux, const char *pnp) 125atabusprint(void *aux, const char *pnp)
122{ 126{
123 struct ata_channel *chan = aux; 127 struct ata_channel *chan = aux;
124 128
125 if (pnp) 129 if (pnp)
@@ -164,59 +168,107 @@ ata_channel_attach(struct ata_channel *c @@ -164,59 +168,107 @@ ata_channel_attach(struct ata_channel *c
164 chp->ch_queue->queue_freeze = 0; 168 chp->ch_queue->queue_freeze = 0;
165 chp->ch_queue->queue_flags = 0; 169 chp->ch_queue->queue_flags = 0;
166 chp->ch_queue->active_xfer = NULL; 170 chp->ch_queue->active_xfer = NULL;
167 171
168 chp->atabus = config_found_ia(chp->ch_atac->atac_dev, "ata", chp, 172 chp->atabus = config_found_ia(chp->ch_atac->atac_dev, "ata", chp,
169 atabusprint); 173 atabusprint);
170} 174}
171 175
172static void 176static void
173atabusconfig(struct atabus_softc *atabus_sc) 177atabusconfig(struct atabus_softc *atabus_sc)
174{ 178{
175 struct ata_channel *chp = atabus_sc->sc_chan; 179 struct ata_channel *chp = atabus_sc->sc_chan;
176 struct atac_softc *atac = chp->ch_atac; 180 struct atac_softc *atac = chp->ch_atac;
177 int i, s; 
178 struct atabus_initq *atabus_initq = NULL; 181 struct atabus_initq *atabus_initq = NULL;
 182 int i, s, error;
 183
 184 /* we are in the atabus's thread context */
 185 s = splbio();
 186 chp->ch_flags |= ATACH_TH_RUN;
 187 splx(s);
179 188
180 /* Probe for the drives. */ 189 /* Probe for the drives. */
181 /* XXX for SATA devices we will power up all drives at once */ 190 /* XXX for SATA devices we will power up all drives at once */
182 (*atac->atac_probe)(chp); 191 (*atac->atac_probe)(chp);
183 192
184 ATADEBUG_PRINT(("atabusattach: ch_drive_flags 0x%x 0x%x\n", 193 ATADEBUG_PRINT(("atabusattach: ch_drive_flags 0x%x 0x%x\n",
185 chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags), 194 chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags),
186 DEBUG_PROBE); 195 DEBUG_PROBE);
187 196
 197 /* next operations will occurs in a separate thread */
 198 s = splbio();
 199 chp->ch_flags &= ~ATACH_TH_RUN;
 200 splx(s);
 201
 202 /* Make sure the devices probe in atabus order to avoid jitter. */
 203 simple_lock(&atabus_interlock);
 204 while(1) {
 205 atabus_initq = TAILQ_FIRST(&atabus_initq_head);
 206 if (atabus_initq->atabus_sc == atabus_sc)
 207 break;
 208 ltsleep(&atabus_initq_head, PRIBIO, "ata_initq", 0,
 209 &atabus_interlock);
 210 }
 211 simple_unlock(&atabus_interlock);
 212
188 /* If no drives, abort here */ 213 /* If no drives, abort here */
189 for (i = 0; i < chp->ch_ndrive; i++) 214 for (i = 0; i < chp->ch_ndrive; i++)
190 if ((chp->ch_drive[i].drive_flags & DRIVE) != 0) 215 if ((chp->ch_drive[i].drive_flags & DRIVE) != 0)
191 break; 216 break;
192 if (i == chp->ch_ndrive) 217 if (i == chp->ch_ndrive)
193 goto out; 218 goto out;
194 219
195 /* Shortcut in case we've been shutdown */ 220 /* Shortcut in case we've been shutdown */
196 if (chp->ch_flags & ATACH_SHUTDOWN) 221 if (chp->ch_flags & ATACH_SHUTDOWN)
197 goto out; 222 goto out;
198 223
199 /* Make sure the devices probe in atabus order to avoid jitter. */ 224
 225 if ((error = kthread_create(PRI_NONE, 0, NULL, atabusconfig_thread,
 226 atabus_sc, &atabus_configlwp,
 227 "%scnf", device_xname(atac->atac_dev))) != 0)
 228 aprint_error_dev(atac->atac_dev,
 229 "unable to create config thread: error %d\n", error);
 230 return;
 231
 232 out:
200 simple_lock(&atabus_interlock); 233 simple_lock(&atabus_interlock);
201 while(1) { 234 TAILQ_REMOVE(&atabus_initq_head, atabus_initq, atabus_initq);
202 atabus_initq = TAILQ_FIRST(&atabus_initq_head); 
203 if (atabus_initq->atabus_sc == atabus_sc) 
204 break; 
205 ltsleep(&atabus_initq_head, PRIBIO, "ata_initq", 0, 
206 &atabus_interlock); 
207 } 
208 simple_unlock(&atabus_interlock); 235 simple_unlock(&atabus_interlock);
209 236
 237 free(atabus_initq, M_DEVBUF);
 238 wakeup(&atabus_initq_head);
 239
 240 ata_delref(chp);
 241
 242 config_pending_decr();
 243}
 244
 245/*
 246 * atabus_configthread: finish attach of atabus's childrens, in a separate
 247 * kernel thread.
 248 */
 249static void
 250atabusconfig_thread(void *arg)
 251{
 252 struct atabus_softc *atabus_sc = arg;
 253 struct ata_channel *chp = atabus_sc->sc_chan;
 254 struct atac_softc *atac = chp->ch_atac;
 255 int i, s;
 256 struct atabus_initq *atabus_initq = NULL;
 257
 258 simple_lock(&atabus_interlock);
 259 atabus_initq = TAILQ_FIRST(&atabus_initq_head);
 260 simple_unlock(&atabus_interlock);
 261 KASSERT(atabus_initq->atabus_sc == atabus_sc);
210 /* 262 /*
211 * Attach an ATAPI bus, if needed. 263 * Attach an ATAPI bus, if needed.
212 */ 264 */
213 for (i = 0; i < chp->ch_ndrive; i++) { 265 for (i = 0; i < chp->ch_ndrive; i++) {
214 if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI) { 266 if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI) {
215#if NATAPIBUS > 0 267#if NATAPIBUS > 0
216 (*atac->atac_atapibus_attach)(atabus_sc); 268 (*atac->atac_atapibus_attach)(atabus_sc);
217#else 269#else
218 /* 270 /*
219 * Fake the autoconfig "not configured" message 271 * Fake the autoconfig "not configured" message
220 */ 272 */
221 aprint_normal("atapibus at %s not configured\n", 273 aprint_normal("atapibus at %s not configured\n",
222 device_xname(atac->atac_dev)); 274 device_xname(atac->atac_dev));
@@ -268,48 +320,37 @@ atabusconfig(struct atabus_softc *atabus @@ -268,48 +320,37 @@ atabusconfig(struct atabus_softc *atabus
268 /* 320 /*
269 * reset drive_flags for unattached devices, reset state for attached 321 * reset drive_flags for unattached devices, reset state for attached
270 * ones 322 * ones
271 */ 323 */
272 s = splbio(); 324 s = splbio();
273 for (i = 0; i < chp->ch_ndrive; i++) { 325 for (i = 0; i < chp->ch_ndrive; i++) {
274 if (chp->ch_drive[i].drv_softc == NULL) 326 if (chp->ch_drive[i].drv_softc == NULL)
275 chp->ch_drive[i].drive_flags = 0; 327 chp->ch_drive[i].drive_flags = 0;
276 else 328 else
277 chp->ch_drive[i].state = 0; 329 chp->ch_drive[i].state = 0;
278 } 330 }
279 splx(s); 331 splx(s);
280 332
281 out: 
282 if (atabus_initq == NULL) { 
283 simple_lock(&atabus_interlock); 
284 while(1) { 
285 atabus_initq = TAILQ_FIRST(&atabus_initq_head); 
286 if (atabus_initq->atabus_sc == atabus_sc) 
287 break; 
288 ltsleep(&atabus_initq_head, PRIBIO, "ata_initq", 0, 
289 &atabus_interlock); 
290 } 
291 simple_unlock(&atabus_interlock); 
292 } 
293 simple_lock(&atabus_interlock); 333 simple_lock(&atabus_interlock);
294 TAILQ_REMOVE(&atabus_initq_head, atabus_initq, atabus_initq); 334 TAILQ_REMOVE(&atabus_initq_head, atabus_initq, atabus_initq);
295 simple_unlock(&atabus_interlock); 335 simple_unlock(&atabus_interlock);
296 336
297 free(atabus_initq, M_DEVBUF); 337 free(atabus_initq, M_DEVBUF);
298 wakeup(&atabus_initq_head); 338 wakeup(&atabus_initq_head);
299 339
300 ata_delref(chp); 340 ata_delref(chp);
301 341
302 config_pending_decr(); 342 config_pending_decr();
 343 kthread_exit(0);
303} 344}
304 345
305/* 346/*
306 * atabus_thread: 347 * atabus_thread:
307 * 348 *
308 * Worker thread for the ATA bus. 349 * Worker thread for the ATA bus.
309 */ 350 */
310static void 351static void
311atabus_thread(void *arg) 352atabus_thread(void *arg)
312{ 353{
313 struct atabus_softc *sc = arg; 354 struct atabus_softc *sc = arg;
314 struct ata_channel *chp = sc->sc_chan; 355 struct ata_channel *chp = sc->sc_chan;
315 struct ata_xfer *xfer; 356 struct ata_xfer *xfer;
@@ -971,26 +1012,28 @@ ata_reset_channel(struct ata_channel *ch @@ -971,26 +1012,28 @@ ata_reset_channel(struct ata_channel *ch
971 printf("ata_reset_channel: not at splbio()\n"); 1012 printf("ata_reset_channel: not at splbio()\n");
972 panic("ata_reset_channel"); 1013 panic("ata_reset_channel");
973 } 1014 }
974 splx(spl2); 1015 splx(spl2);
975 splx(spl1); 1016 splx(spl1);
976#endif /* ATA_DEBUG */ 1017#endif /* ATA_DEBUG */
977 1018
978 chp->ch_queue->queue_freeze++; 1019 chp->ch_queue->queue_freeze++;
979 1020
980 /* 1021 /*
981 * If we can poll or wait it's OK, otherwise wake up the 1022 * If we can poll or wait it's OK, otherwise wake up the
982 * kernel thread to do it for us. 1023 * kernel thread to do it for us.
983 */ 1024 */
 1025 ATADEBUG_PRINT(("ata_reset_channel flags 0x%x ch_flags 0x%x\n",
 1026 flags, chp->ch_flags), DEBUG_FUNCS | DEBUG_XFERS);
984 if ((flags & (AT_POLL | AT_WAIT)) == 0) { 1027 if ((flags & (AT_POLL | AT_WAIT)) == 0) {
985 if (chp->ch_flags & ATACH_TH_RESET) { 1028 if (chp->ch_flags & ATACH_TH_RESET) {
986 /* No need to schedule a reset more than one time. */ 1029 /* No need to schedule a reset more than one time. */
987 chp->ch_queue->queue_freeze--; 1030 chp->ch_queue->queue_freeze--;
988 return; 1031 return;
989 } 1032 }
990 chp->ch_flags |= ATACH_TH_RESET; 1033 chp->ch_flags |= ATACH_TH_RESET;
991 chp->ch_reset_flags = flags & (AT_RST_EMERG | AT_RST_NOCMD); 1034 chp->ch_reset_flags = flags & (AT_RST_EMERG | AT_RST_NOCMD);
992 wakeup(&chp->ch_thread); 1035 wakeup(&chp->ch_thread);
993 return; 1036 return;
994 } 1037 }
995 1038
996 (*atac->atac_bustype_ata->ata_reset_channel)(chp, flags); 1039 (*atac->atac_bustype_ata->ata_reset_channel)(chp, flags);