1 1.306 mlelstv /* $NetBSD: scsiconf.c,v 1.306 2024/11/22 06:52:57 mlelstv Exp $ */ 2 1.14 cgd 3 1.106 mycroft /*- 4 1.223 mycroft * Copyright (c) 1998, 1999, 2004 The NetBSD Foundation, Inc. 5 1.106 mycroft * All rights reserved. 6 1.106 mycroft * 7 1.106 mycroft * This code is derived from software contributed to The NetBSD Foundation 8 1.111 thorpej * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace 9 1.111 thorpej * Simulation Facility, NASA Ames Research Center. 10 1.12 mycroft * 11 1.12 mycroft * Redistribution and use in source and binary forms, with or without 12 1.12 mycroft * modification, are permitted provided that the following conditions 13 1.12 mycroft * are met: 14 1.12 mycroft * 1. Redistributions of source code must retain the above copyright 15 1.12 mycroft * notice, this list of conditions and the following disclaimer. 16 1.12 mycroft * 2. Redistributions in binary form must reproduce the above copyright 17 1.12 mycroft * notice, this list of conditions and the following disclaimer in the 18 1.12 mycroft * documentation and/or other materials provided with the distribution. 19 1.12 mycroft * 20 1.106 mycroft * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.106 mycroft * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.106 mycroft * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.106 mycroft * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.106 mycroft * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.106 mycroft * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.106 mycroft * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.106 mycroft * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.106 mycroft * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.106 mycroft * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.106 mycroft * POSSIBILITY OF SUCH DAMAGE. 31 1.12 mycroft */ 32 1.12 mycroft 33 1.12 mycroft /* 34 1.12 mycroft * Originally written by Julian Elischer (julian (at) tfs.com) 35 1.5 deraadt * for TRW Financial Systems for use under the MACH(2.5) operating system. 36 1.1 cgd * 37 1.1 cgd * TRW Financial Systems, in accordance with their agreement with Carnegie 38 1.1 cgd * Mellon University, makes this software available to CMU to distribute 39 1.1 cgd * or use in any manner that they see fit as long as this message is kept with 40 1.1 cgd * the software. For this reason TFS also grants any other persons or 41 1.1 cgd * organisations permission to use or modify this software. 42 1.1 cgd * 43 1.1 cgd * TFS supplies this software to be publicly redistributed 44 1.1 cgd * on the understanding that TFS is not responsible for the correct 45 1.1 cgd * functioning of this software in any circumstances. 46 1.7 cgd * 47 1.12 mycroft * Ported to run under 386BSD by Julian Elischer (julian (at) tfs.com) Sept 1992 48 1.1 cgd */ 49 1.165 lukem 50 1.165 lukem #include <sys/cdefs.h> 51 1.306 mlelstv __KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.306 2024/11/22 06:52:57 mlelstv Exp $"); 52 1.1 cgd 53 1.10 mycroft #include <sys/param.h> 54 1.10 mycroft #include <sys/systm.h> 55 1.128 thorpej #include <sys/kernel.h> 56 1.128 thorpej #include <sys/proc.h> 57 1.157 bouyer #include <sys/kthread.h> 58 1.12 mycroft #include <sys/malloc.h> 59 1.260 rmind #include <sys/mutex.h> 60 1.260 rmind #include <sys/once.h> 61 1.12 mycroft #include <sys/device.h> 62 1.111 thorpej #include <sys/conf.h> 63 1.113 thorpej #include <sys/fcntl.h> 64 1.112 thorpej #include <sys/scsiio.h> 65 1.188 jmc #include <sys/queue.h> 66 1.277 mlelstv #include <sys/atomic.h> 67 1.294 jakllsch #include <sys/kmem.h> 68 1.10 mycroft 69 1.88 bouyer #include <dev/scsipi/scsi_all.h> 70 1.88 bouyer #include <dev/scsipi/scsipi_all.h> 71 1.88 bouyer #include <dev/scsipi/scsiconf.h> 72 1.92 enami 73 1.88 bouyer #include "locators.h" 74 1.1 cgd 75 1.226 thorpej static const struct scsipi_periphsw scsi_probe_dev = { 76 1.12 mycroft NULL, 77 1.12 mycroft NULL, 78 1.12 mycroft NULL, 79 1.12 mycroft NULL, 80 1.12 mycroft }; 81 1.12 mycroft 82 1.188 jmc struct scsi_initq { 83 1.188 jmc struct scsipi_channel *sc_channel; 84 1.188 jmc TAILQ_ENTRY(scsi_initq) scsi_initq; 85 1.188 jmc }; 86 1.188 jmc 87 1.260 rmind static ONCE_DECL(scsi_conf_ctrl); 88 1.260 rmind static TAILQ_HEAD(, scsi_initq) scsi_initq_head; 89 1.260 rmind static kmutex_t scsibus_qlock; 90 1.260 rmind static kcondvar_t scsibus_qcv; 91 1.188 jmc 92 1.226 thorpej static int scsi_probe_device(struct scsibus_softc *, int, int); 93 1.157 bouyer 94 1.253 cegger static int scsibusmatch(device_t, cfdata_t, void *); 95 1.253 cegger static void scsibusattach(device_t, device_t, void *); 96 1.253 cegger static int scsibusdetach(device_t, int flags); 97 1.253 cegger static int scsibusrescan(device_t, const char *, const int *); 98 1.253 cegger static void scsidevdetached(device_t, device_t); 99 1.126 thorpej 100 1.251 dyoung CFATTACH_DECL3_NEW(scsibus, sizeof(struct scsibus_softc), 101 1.255 dyoung scsibusmatch, scsibusattach, scsibusdetach, NULL, 102 1.251 dyoung scsibusrescan, scsidevdetached, DVF_DETACH_SHUTDOWN); 103 1.53 thorpej 104 1.94 thorpej extern struct cfdriver scsibus_cd; 105 1.12 mycroft 106 1.226 thorpej static dev_type_open(scsibusopen); 107 1.226 thorpej static dev_type_close(scsibusclose); 108 1.226 thorpej static dev_type_ioctl(scsibusioctl); 109 1.187 gehenna 110 1.187 gehenna const struct cdevsw scsibus_cdevsw = { 111 1.272 dholland .d_open = scsibusopen, 112 1.272 dholland .d_close = scsibusclose, 113 1.272 dholland .d_read = noread, 114 1.272 dholland .d_write = nowrite, 115 1.272 dholland .d_ioctl = scsibusioctl, 116 1.272 dholland .d_stop = nostop, 117 1.272 dholland .d_tty = notty, 118 1.272 dholland .d_poll = nopoll, 119 1.272 dholland .d_mmap = nommap, 120 1.272 dholland .d_kqfilter = nokqfilter, 121 1.273 dholland .d_discard = nodiscard, 122 1.276 mlelstv .d_flag = D_OTHER | D_MPSAFE 123 1.187 gehenna }; 124 1.187 gehenna 125 1.226 thorpej static int scsibusprint(void *, const char *); 126 1.275 mlelstv static void scsibus_discover_thread(void *); 127 1.275 mlelstv static void scsibus_config(struct scsibus_softc *); 128 1.62 cgd 129 1.260 rmind static int 130 1.260 rmind scsibus_init(void) 131 1.260 rmind { 132 1.260 rmind 133 1.260 rmind TAILQ_INIT(&scsi_initq_head); 134 1.260 rmind mutex_init(&scsibus_qlock, MUTEX_DEFAULT, IPL_NONE); 135 1.260 rmind cv_init(&scsibus_qcv, "scsinitq"); 136 1.260 rmind return 0; 137 1.260 rmind } 138 1.260 rmind 139 1.226 thorpej static int 140 1.253 cegger scsibusmatch(device_t parent, cfdata_t cf, void *aux) 141 1.12 mycroft { 142 1.157 bouyer struct scsipi_channel *chan = aux; 143 1.62 cgd 144 1.266 bouyer if (SCSIPI_BUSTYPE_TYPE(chan->chan_bustype->bustype_type) != 145 1.266 bouyer SCSIPI_BUSTYPE_SCSI) 146 1.157 bouyer return 0; 147 1.62 cgd 148 1.157 bouyer if (cf->cf_loc[SCSICF_CHANNEL] != chan->chan_channel && 149 1.92 enami cf->cf_loc[SCSICF_CHANNEL] != SCSICF_CHANNEL_DEFAULT) 150 1.62 cgd return (0); 151 1.12 mycroft 152 1.62 cgd return (1); 153 1.12 mycroft } 154 1.12 mycroft 155 1.226 thorpej static void 156 1.253 cegger scsibusattach(device_t parent, device_t self, void *aux) 157 1.12 mycroft { 158 1.236 thorpej struct scsibus_softc *sc = device_private(self); 159 1.157 bouyer struct scsipi_channel *chan = aux; 160 1.188 jmc struct scsi_initq *scsi_initq; 161 1.103 thorpej 162 1.244 jmcneill if (!pmf_device_register(self, NULL, NULL)) 163 1.244 jmcneill aprint_error_dev(self, "couldn't establish power handler\n"); 164 1.244 jmcneill 165 1.250 drochner sc->sc_dev = self; 166 1.157 bouyer sc->sc_channel = chan; 167 1.250 drochner chan->chan_name = device_xname(sc->sc_dev); 168 1.72 thorpej 169 1.205 thorpej aprint_naive(": SCSI bus\n"); 170 1.205 thorpej aprint_normal(": %d target%s, %d lun%s per target\n", 171 1.188 jmc chan->chan_ntargets, 172 1.188 jmc chan->chan_ntargets == 1 ? "" : "s", 173 1.188 jmc chan->chan_nluns, 174 1.188 jmc chan->chan_nluns == 1 ? "" : "s"); 175 1.188 jmc 176 1.269 bouyer /* 177 1.269 bouyer * XXX 178 1.269 bouyer * newer adapters support more than 256 outstanding commands 179 1.269 bouyer * per periph and don't use the tag (they eventually allocate one 180 1.269 bouyer * internally). Right now scsipi always allocate a tag and 181 1.269 bouyer * is limited to 256 tags, per scsi specs. 182 1.269 bouyer * this should be revisited 183 1.269 bouyer */ 184 1.269 bouyer if (chan->chan_flags & SCSIPI_CHAN_OPENINGS) { 185 1.269 bouyer if (chan->chan_max_periph > 256) 186 1.269 bouyer chan->chan_max_periph = 256; 187 1.269 bouyer } else { 188 1.269 bouyer if (chan->chan_adapter->adapt_max_periph > 256) 189 1.269 bouyer chan->chan_adapter->adapt_max_periph = 256; 190 1.269 bouyer } 191 1.269 bouyer 192 1.277 mlelstv if (atomic_inc_uint_nv(&chan_running(chan)) == 1) 193 1.277 mlelstv mutex_init(chan_mtx(chan), MUTEX_DEFAULT, IPL_BIO); 194 1.277 mlelstv 195 1.276 mlelstv cv_init(&chan->chan_cv_thr, "scshut"); 196 1.276 mlelstv cv_init(&chan->chan_cv_comp, "sccomp"); 197 1.276 mlelstv cv_init(&chan->chan_cv_xs, "xscmd"); 198 1.276 mlelstv 199 1.223 mycroft if (scsipi_adapter_addref(chan->chan_adapter)) 200 1.223 mycroft return; 201 1.223 mycroft 202 1.260 rmind RUN_ONCE(&scsi_conf_ctrl, scsibus_init); 203 1.260 rmind 204 1.157 bouyer /* Initialize the channel structure first */ 205 1.275 mlelstv chan->chan_init_cb = NULL; 206 1.275 mlelstv chan->chan_init_cb_arg = NULL; 207 1.229 perry 208 1.188 jmc scsi_initq = malloc(sizeof(struct scsi_initq), M_DEVBUF, M_WAITOK); 209 1.188 jmc scsi_initq->sc_channel = chan; 210 1.188 jmc TAILQ_INSERT_TAIL(&scsi_initq_head, scsi_initq, scsi_initq); 211 1.271 christos config_pending_incr(sc->sc_dev); 212 1.157 bouyer if (scsipi_channel_init(chan)) { 213 1.250 drochner aprint_error_dev(sc->sc_dev, "failed to init channel\n"); 214 1.157 bouyer return; 215 1.72 thorpej } 216 1.275 mlelstv 217 1.275 mlelstv /* 218 1.275 mlelstv * Create the discover thread 219 1.275 mlelstv */ 220 1.275 mlelstv if (kthread_create(PRI_NONE, 0, NULL, scsibus_discover_thread, sc, 221 1.281 mlelstv &chan->chan_dthread, "%s-d", chan->chan_name)) { 222 1.275 mlelstv aprint_error_dev(sc->sc_dev, "unable to create discovery " 223 1.275 mlelstv "thread for channel %d\n", chan->chan_channel); 224 1.275 mlelstv return; 225 1.275 mlelstv } 226 1.128 thorpej } 227 1.128 thorpej 228 1.226 thorpej static void 229 1.275 mlelstv scsibus_discover_thread(void *arg) 230 1.128 thorpej { 231 1.188 jmc struct scsibus_softc *sc = arg; 232 1.275 mlelstv 233 1.275 mlelstv scsibus_config(sc); 234 1.281 mlelstv sc->sc_channel->chan_dthread = NULL; 235 1.275 mlelstv kthread_exit(0); 236 1.275 mlelstv } 237 1.275 mlelstv 238 1.275 mlelstv static void 239 1.275 mlelstv scsibus_config(struct scsibus_softc *sc) 240 1.275 mlelstv { 241 1.275 mlelstv struct scsipi_channel *chan = sc->sc_channel; 242 1.188 jmc struct scsi_initq *scsi_initq; 243 1.157 bouyer 244 1.132 soren #ifndef SCSI_DELAY 245 1.12 mycroft #define SCSI_DELAY 2 246 1.132 soren #endif 247 1.201 bouyer if ((chan->chan_flags & SCSIPI_CHAN_NOSETTLE) == 0 && 248 1.201 bouyer SCSI_DELAY > 0) { 249 1.250 drochner aprint_normal_dev(sc->sc_dev, 250 1.246 cegger "waiting %d seconds for devices to settle...\n", 251 1.246 cegger SCSI_DELAY); 252 1.201 bouyer /* ...an identifier we know no one will use... */ 253 1.276 mlelstv kpause("scsidly", false, SCSI_DELAY * hz, NULL); 254 1.201 bouyer } 255 1.157 bouyer 256 1.188 jmc /* Make sure the devices probe in scsibus order to avoid jitter. */ 257 1.260 rmind mutex_enter(&scsibus_qlock); 258 1.188 jmc for (;;) { 259 1.188 jmc scsi_initq = TAILQ_FIRST(&scsi_initq_head); 260 1.188 jmc if (scsi_initq->sc_channel == chan) 261 1.188 jmc break; 262 1.260 rmind cv_wait(&scsibus_qcv, &scsibus_qlock); 263 1.188 jmc } 264 1.260 rmind mutex_exit(&scsibus_qlock); 265 1.128 thorpej 266 1.157 bouyer scsi_probe_bus(sc, -1, -1); 267 1.188 jmc 268 1.260 rmind mutex_enter(&scsibus_qlock); 269 1.188 jmc TAILQ_REMOVE(&scsi_initq_head, scsi_initq, scsi_initq); 270 1.260 rmind cv_broadcast(&scsibus_qcv); 271 1.260 rmind mutex_exit(&scsibus_qlock); 272 1.188 jmc 273 1.188 jmc free(scsi_initq, M_DEVBUF); 274 1.188 jmc 275 1.224 mycroft scsipi_adapter_delref(chan->chan_adapter); 276 1.224 mycroft 277 1.271 christos config_pending_decr(sc->sc_dev); 278 1.12 mycroft } 279 1.12 mycroft 280 1.226 thorpej static int 281 1.253 cegger scsibusdetach(device_t self, int flags) 282 1.126 thorpej { 283 1.236 thorpej struct scsibus_softc *sc = device_private(self); 284 1.157 bouyer struct scsipi_channel *chan = sc->sc_channel; 285 1.222 bouyer int error; 286 1.221 bouyer 287 1.262 hannken /* 288 1.281 mlelstv * Defer while discovery thread is running 289 1.281 mlelstv */ 290 1.281 mlelstv while (chan->chan_dthread != NULL) 291 1.281 mlelstv kpause("scsibusdet", false, hz, NULL); 292 1.281 mlelstv 293 1.281 mlelstv /* 294 1.262 hannken * Detach all of the periphs. 295 1.262 hannken */ 296 1.280 mlelstv error = scsipi_target_detach(chan, -1, -1, flags); 297 1.280 mlelstv if (error) 298 1.262 hannken return error; 299 1.262 hannken 300 1.244 jmcneill pmf_device_deregister(self); 301 1.126 thorpej 302 1.157 bouyer /* 303 1.280 mlelstv * Shut down the channel. 304 1.221 bouyer */ 305 1.221 bouyer scsipi_channel_shutdown(chan); 306 1.264 mrg 307 1.276 mlelstv cv_destroy(&chan->chan_cv_xs); 308 1.276 mlelstv cv_destroy(&chan->chan_cv_comp); 309 1.276 mlelstv cv_destroy(&chan->chan_cv_thr); 310 1.277 mlelstv 311 1.301 riastrad membar_release(); 312 1.299 riastrad if (atomic_dec_uint_nv(&chan_running(chan)) == 0) { 313 1.301 riastrad membar_acquire(); 314 1.277 mlelstv mutex_destroy(chan_mtx(chan)); 315 1.299 riastrad } 316 1.264 mrg 317 1.262 hannken return 0; 318 1.18 mycroft } 319 1.18 mycroft 320 1.294 jakllsch static int 321 1.294 jakllsch lun_compar(const void *a, const void *b) 322 1.294 jakllsch { 323 1.294 jakllsch const uint16_t * const la = a, * const lb = b; 324 1.294 jakllsch 325 1.294 jakllsch if (*la < *lb) 326 1.294 jakllsch return -1; 327 1.294 jakllsch if (*la > *lb) 328 1.294 jakllsch return 1; 329 1.294 jakllsch return 0; 330 1.294 jakllsch } 331 1.294 jakllsch 332 1.294 jakllsch static int 333 1.294 jakllsch scsi_report_luns(struct scsibus_softc *sc, int target, 334 1.294 jakllsch uint16_t ** const luns, size_t *nluns) 335 1.294 jakllsch { 336 1.294 jakllsch struct scsi_report_luns replun; 337 1.294 jakllsch struct scsi_report_luns_header *rlr; 338 1.294 jakllsch struct scsi_report_luns_lun *lunp; 339 1.294 jakllsch 340 1.294 jakllsch struct scsipi_channel *chan = sc->sc_channel; 341 1.294 jakllsch struct scsipi_inquiry_data inqbuf; 342 1.294 jakllsch struct scsipi_periph *periph; 343 1.294 jakllsch uint16_t tmp; 344 1.294 jakllsch 345 1.294 jakllsch int error; 346 1.300 riastrad size_t i, rlrlen, rlrlenmin; 347 1.294 jakllsch 348 1.298 hannken memset(&replun, 0, sizeof(replun)); 349 1.298 hannken 350 1.294 jakllsch periph = scsipi_alloc_periph(M_WAITOK); 351 1.294 jakllsch periph->periph_channel = chan; 352 1.294 jakllsch periph->periph_switch = &scsi_probe_dev; 353 1.294 jakllsch 354 1.294 jakllsch periph->periph_target = target; 355 1.294 jakllsch periph->periph_lun = 0; 356 1.294 jakllsch periph->periph_quirks = chan->chan_defquirks; 357 1.294 jakllsch 358 1.294 jakllsch if ((error = scsipi_inquire(periph, &inqbuf, 359 1.294 jakllsch XS_CTL_DISCOVERY | XS_CTL_SILENT))) 360 1.294 jakllsch goto end2; 361 1.294 jakllsch periph->periph_version = inqbuf.version & SID_ANSII; 362 1.294 jakllsch if (periph->periph_version < 3) { 363 1.294 jakllsch error = ENOTSUP; 364 1.294 jakllsch goto end2; 365 1.294 jakllsch } 366 1.294 jakllsch 367 1.300 riastrad rlrlen = rlrlenmin = sizeof(*rlr) + sizeof(*lunp) * 1; 368 1.294 jakllsch 369 1.294 jakllsch again: 370 1.294 jakllsch rlr = kmem_zalloc(rlrlen, KM_SLEEP); 371 1.294 jakllsch 372 1.294 jakllsch replun.opcode = SCSI_REPORT_LUNS; 373 1.294 jakllsch replun.selectreport = SELECTREPORT_NORMAL; 374 1.294 jakllsch _lto4b(rlrlen, replun.alloclen); 375 1.294 jakllsch 376 1.294 jakllsch error = scsipi_command(periph, (void *)&replun, sizeof(replun), 377 1.294 jakllsch (void *)rlr, rlrlen, SCSIPIRETRIES, 10000, NULL, 378 1.294 jakllsch XS_CTL_DATA_IN | XS_CTL_DISCOVERY | XS_CTL_SILENT); 379 1.294 jakllsch if (error) 380 1.294 jakllsch goto end; 381 1.294 jakllsch 382 1.306 mlelstv if (sizeof(*rlr) + _4btol(rlr->length) > rlrlen) { 383 1.294 jakllsch const size_t old_rlrlen = rlrlen; 384 1.294 jakllsch rlrlen = sizeof(*rlr) + uimin(_4btol(rlr->length), 385 1.294 jakllsch 16383 * sizeof(*lunp)); 386 1.294 jakllsch kmem_free(rlr, old_rlrlen); 387 1.294 jakllsch rlr = NULL; 388 1.300 riastrad if (rlrlen < rlrlenmin) { 389 1.300 riastrad error = EIO; 390 1.300 riastrad goto end; 391 1.300 riastrad } 392 1.294 jakllsch goto again; 393 1.294 jakllsch } 394 1.294 jakllsch 395 1.294 jakllsch KASSERT(nluns != NULL); 396 1.294 jakllsch *nluns = (rlrlen - sizeof(*rlr)) / sizeof(*lunp); 397 1.294 jakllsch 398 1.294 jakllsch KASSERT(luns != NULL); 399 1.294 jakllsch *luns = kmem_alloc(*nluns * sizeof(**luns), KM_SLEEP); 400 1.294 jakllsch 401 1.294 jakllsch for (i = 0; i < *nluns; i++) { 402 1.294 jakllsch lunp = &((struct scsi_report_luns_lun *)&rlr[1])[i]; 403 1.294 jakllsch switch (lunp->lun[0] & 0xC0) { 404 1.294 jakllsch default: 405 1.294 jakllsch scsi_print_addr(periph); 406 1.294 jakllsch printf("LUN %016"PRIx64" ignored\n", _8btol(lunp->lun)); 407 1.294 jakllsch (*luns)[i] = 0; 408 1.294 jakllsch break; 409 1.294 jakllsch case 0x40: 410 1.294 jakllsch (*luns)[i] = _2btol(&lunp->lun[0]) & 0x3FFF; 411 1.294 jakllsch break; 412 1.294 jakllsch case 0x00: 413 1.294 jakllsch (*luns)[i] = _2btol(&lunp->lun[0]) & 0x00FF; 414 1.294 jakllsch break; 415 1.294 jakllsch } 416 1.294 jakllsch } 417 1.294 jakllsch 418 1.294 jakllsch kheapsort(*luns, *nluns, sizeof(**luns), lun_compar, &tmp); 419 1.294 jakllsch 420 1.294 jakllsch end: 421 1.294 jakllsch if (rlr) 422 1.294 jakllsch kmem_free(rlr, rlrlen); 423 1.294 jakllsch end2: 424 1.294 jakllsch scsipi_free_periph(periph); 425 1.294 jakllsch return error; 426 1.294 jakllsch } 427 1.294 jakllsch 428 1.296 christos static void 429 1.296 christos scsi_discover_luns(struct scsibus_softc *sc, int target, int minlun, int maxlun) 430 1.296 christos { 431 1.297 martin uint16_t *luns = NULL; /* XXX gcc */ 432 1.297 martin size_t nluns = 0; /* XXX gcc */ 433 1.296 christos 434 1.296 christos if (scsi_report_luns(sc, target, &luns, &nluns) == 0) { 435 1.296 christos for (size_t i = 0; i < nluns; i++) 436 1.296 christos if (luns[i] >= minlun && luns[i] <= maxlun) 437 1.296 christos scsi_probe_device(sc, target, luns[i]); 438 1.296 christos kmem_free(luns, sizeof(*luns) * nluns); 439 1.296 christos return; 440 1.296 christos } 441 1.296 christos 442 1.296 christos for (int lun = minlun; lun <= maxlun; lun++) { 443 1.296 christos /* 444 1.296 christos * See if there's a device present, and configure it. 445 1.296 christos */ 446 1.296 christos if (scsi_probe_device(sc, target, lun) == 0) 447 1.296 christos break; 448 1.296 christos /* otherwise something says we should look further */ 449 1.296 christos } 450 1.296 christos } 451 1.296 christos 452 1.12 mycroft /* 453 1.12 mycroft * Probe the requested scsi bus. It must be already set up. 454 1.18 mycroft * target and lun optionally narrow the search if not -1 455 1.12 mycroft */ 456 1.12 mycroft int 457 1.226 thorpej scsi_probe_bus(struct scsibus_softc *sc, int target, int lun) 458 1.12 mycroft { 459 1.157 bouyer struct scsipi_channel *chan = sc->sc_channel; 460 1.18 mycroft int maxtarget, mintarget, maxlun, minlun; 461 1.116 thorpej int error; 462 1.12 mycroft 463 1.18 mycroft if (target == -1) { 464 1.157 bouyer maxtarget = chan->chan_ntargets - 1; 465 1.18 mycroft mintarget = 0; 466 1.12 mycroft } else { 467 1.157 bouyer if (target < 0 || target >= chan->chan_ntargets) 468 1.92 enami return (EINVAL); 469 1.18 mycroft maxtarget = mintarget = target; 470 1.12 mycroft } 471 1.1 cgd 472 1.12 mycroft if (lun == -1) { 473 1.157 bouyer maxlun = chan->chan_nluns - 1; 474 1.12 mycroft minlun = 0; 475 1.12 mycroft } else { 476 1.157 bouyer if (lun < 0 || lun >= chan->chan_nluns) 477 1.92 enami return (EINVAL); 478 1.12 mycroft maxlun = minlun = lun; 479 1.12 mycroft } 480 1.12 mycroft 481 1.153 ad /* 482 1.153 ad * Some HBAs provide an abstracted view of the bus; give them an 483 1.289 jakllsch * opportunity to re-scan it before we do. 484 1.153 ad */ 485 1.276 mlelstv scsipi_adapter_ioctl(chan, SCBUSIOLLSCAN, NULL, 0, curproc); 486 1.153 ad 487 1.157 bouyer if ((error = scsipi_adapter_addref(chan->chan_adapter)) != 0) 488 1.268 jakllsch goto ret; 489 1.18 mycroft for (target = mintarget; target <= maxtarget; target++) { 490 1.157 bouyer if (target == chan->chan_id) 491 1.12 mycroft continue; 492 1.229 perry 493 1.296 christos scsi_discover_luns(sc, target, minlun, maxlun); 494 1.294 jakllsch 495 1.157 bouyer /* 496 1.157 bouyer * Now that we've discovered all of the LUNs on this 497 1.157 bouyer * I_T Nexus, update the xfer mode for all of them 498 1.157 bouyer * that we know about. 499 1.157 bouyer */ 500 1.157 bouyer scsipi_set_xfer_mode(chan, target, 1); 501 1.8 deraadt } 502 1.281 mlelstv 503 1.157 bouyer scsipi_adapter_delref(chan->chan_adapter); 504 1.268 jakllsch ret: 505 1.268 jakllsch return (error); 506 1.12 mycroft } 507 1.12 mycroft 508 1.226 thorpej static int 509 1.291 thorpej scsibusrescan(device_t sc, const char *ifattr, const int *locators) 510 1.225 drochner { 511 1.225 drochner 512 1.225 drochner KASSERT(ifattr && !strcmp(ifattr, "scsibus")); 513 1.225 drochner KASSERT(locators); 514 1.225 drochner 515 1.250 drochner return (scsi_probe_bus(device_private(sc), 516 1.225 drochner locators[SCSIBUSCF_TARGET], locators[SCSIBUSCF_LUN])); 517 1.225 drochner } 518 1.225 drochner 519 1.226 thorpej static void 520 1.256 dyoung scsidevdetached(device_t self, device_t child) 521 1.225 drochner { 522 1.256 dyoung struct scsibus_softc *sc = device_private(self); 523 1.256 dyoung struct scsipi_channel *chan = sc->sc_channel; 524 1.225 drochner struct scsipi_periph *periph; 525 1.225 drochner int target, lun; 526 1.225 drochner 527 1.256 dyoung target = device_locator(child, SCSIBUSCF_TARGET); 528 1.256 dyoung lun = device_locator(child, SCSIBUSCF_LUN); 529 1.225 drochner 530 1.276 mlelstv mutex_enter(chan_mtx(chan)); 531 1.263 mrg 532 1.276 mlelstv periph = scsipi_lookup_periph_locked(chan, target, lun); 533 1.278 mlelstv KASSERT(periph != NULL && periph->periph_dev == child); 534 1.225 drochner 535 1.225 drochner scsipi_remove_periph(chan, periph); 536 1.276 mlelstv scsipi_free_periph(periph); 537 1.263 mrg 538 1.276 mlelstv mutex_exit(chan_mtx(chan)); 539 1.225 drochner } 540 1.225 drochner 541 1.88 bouyer /* 542 1.88 bouyer * Print out autoconfiguration information for a subdevice. 543 1.88 bouyer * 544 1.88 bouyer * This is a slight abuse of 'standard' autoconfiguration semantics, 545 1.88 bouyer * because 'print' functions don't normally print the colon and 546 1.88 bouyer * device information. However, in this case that's better than 547 1.88 bouyer * either printing redundant information before the attach message, 548 1.88 bouyer * or having the device driver call a special function to print out 549 1.88 bouyer * the standard device information. 550 1.88 bouyer */ 551 1.226 thorpej static int 552 1.226 thorpej scsibusprint(void *aux, const char *pnp) 553 1.12 mycroft { 554 1.88 bouyer struct scsipibus_attach_args *sa = aux; 555 1.88 bouyer struct scsipi_inquiry_pattern *inqbuf; 556 1.228 reinoud u_int8_t type; 557 1.193 soren const char *dtype; 558 1.88 bouyer char vendor[33], product[65], revision[17]; 559 1.88 bouyer int target, lun; 560 1.88 bouyer 561 1.88 bouyer if (pnp != NULL) 562 1.196 thorpej aprint_normal("%s", pnp); 563 1.88 bouyer 564 1.88 bouyer inqbuf = &sa->sa_inqbuf; 565 1.88 bouyer 566 1.157 bouyer target = sa->sa_periph->periph_target; 567 1.157 bouyer lun = sa->sa_periph->periph_lun; 568 1.88 bouyer type = inqbuf->type & SID_TYPE; 569 1.88 bouyer 570 1.193 soren dtype = scsipi_dtype(type); 571 1.2 deraadt 572 1.274 christos strnvisx(vendor, sizeof(vendor), inqbuf->vendor, 8, 573 1.274 christos VIS_TRIM|VIS_SAFE|VIS_OCTAL); 574 1.274 christos strnvisx(product, sizeof(product), inqbuf->product, 16, 575 1.274 christos VIS_TRIM|VIS_SAFE|VIS_OCTAL); 576 1.274 christos strnvisx(revision, sizeof(revision), inqbuf->revision, 4, 577 1.274 christos VIS_TRIM|VIS_SAFE|VIS_OCTAL); 578 1.88 bouyer 579 1.284 kardel aprint_normal(" target %d lun %d: <%s, %s, %s> %s %s%s", 580 1.284 kardel target, lun, vendor, product, revision, dtype, 581 1.284 kardel inqbuf->removable ? "removable" : "fixed", 582 1.284 kardel (sa->sa_periph->periph_opcs != NULL) 583 1.284 kardel ? " timeout-info" : ""); 584 1.88 bouyer 585 1.88 bouyer return (UNCONF); 586 1.12 mycroft } 587 1.1 cgd 588 1.226 thorpej static const struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = { 589 1.265 christos {{T_DIRECT, T_REMOV, 590 1.265 christos "Apple ", "iPod ", ""}, PQUIRK_START}, 591 1.48 christos {{T_CDROM, T_REMOV, 592 1.157 bouyer "CHINON ", "CD-ROM CDS-431 ", ""}, PQUIRK_NOLUNS}, 593 1.48 christos {{T_CDROM, T_REMOV, 594 1.208 jrf "CHINON ", "CD-ROM CDS-435 ", ""}, PQUIRK_NOLUNS}, 595 1.208 jrf {{T_CDROM, T_REMOV, 596 1.157 bouyer "Chinon ", "CD-ROM CDS-525 ", ""}, PQUIRK_NOLUNS}, 597 1.48 christos {{T_CDROM, T_REMOV, 598 1.157 bouyer "CHINON ", "CD-ROM CDS-535 ", ""}, PQUIRK_NOLUNS}, 599 1.100 thorpej {{T_CDROM, T_REMOV, 600 1.157 bouyer "DEC ", "RRD42 (C) DEC ", ""}, PQUIRK_NOLUNS}, 601 1.48 christos {{T_CDROM, T_REMOV, 602 1.157 bouyer "DENON ", "DRD-25X ", "V"}, PQUIRK_NOLUNS}, 603 1.148 bouyer {{T_CDROM, T_REMOV, 604 1.157 bouyer "GENERIC ", "CRD-BP2 ", ""}, PQUIRK_NOLUNS}, 605 1.83 mycroft {{T_CDROM, T_REMOV, 606 1.157 bouyer "HP ", "C4324/C4325 ", ""}, PQUIRK_NOLUNS}, 607 1.48 christos {{T_CDROM, T_REMOV, 608 1.157 bouyer "IMS ", "CDD521/10 ", "2.06"}, PQUIRK_NOLUNS}, 609 1.48 christos {{T_CDROM, T_REMOV, 610 1.157 bouyer "MATSHITA", "CD-ROM CR-5XX ", "1.0b"}, PQUIRK_NOLUNS}, 611 1.68 mikel {{T_CDROM, T_REMOV, 612 1.157 bouyer "MEDAVIS ", "RENO CD-ROMX2A ", ""}, PQUIRK_NOLUNS}, 613 1.84 perry {{T_CDROM, T_REMOV, 614 1.157 bouyer "MEDIAVIS", "CDR-H93MV ", "1.3"}, PQUIRK_NOLUNS}, 615 1.199 bouyer {{T_CDROM, T_REMOV, 616 1.199 bouyer "NEC ", "CD-ROM DRIVE:502", ""}, PQUIRK_NOLUNS}, 617 1.48 christos {{T_CDROM, T_REMOV, 618 1.157 bouyer "NEC ", "CD-ROM DRIVE:55 ", ""}, PQUIRK_NOLUNS}, 619 1.48 christos {{T_CDROM, T_REMOV, 620 1.157 bouyer "NEC ", "CD-ROM DRIVE:83 ", ""}, PQUIRK_NOLUNS}, 621 1.48 christos {{T_CDROM, T_REMOV, 622 1.157 bouyer "NEC ", "CD-ROM DRIVE:84 ", ""}, PQUIRK_NOLUNS}, 623 1.48 christos {{T_CDROM, T_REMOV, 624 1.157 bouyer "NEC ", "CD-ROM DRIVE:841", ""}, PQUIRK_NOLUNS}, 625 1.208 jrf {{T_CDROM, T_REMOV, 626 1.229 perry "OLYMPUS ", "CDS620E ", "1.1d"}, 627 1.208 jrf PQUIRK_NOLUNS|PQUIRK_NOSYNC|PQUIRK_NOCAPACITY}, 628 1.70 thorpej {{T_CDROM, T_REMOV, 629 1.157 bouyer "PIONEER ", "CD-ROM DR-124X ", "1.01"}, PQUIRK_NOLUNS}, 630 1.208 jrf {{T_CDROM, T_REMOV, 631 1.208 jrf "PLEXTOR ", "CD-ROM PX-4XCS ", "1.01"}, 632 1.208 jrf PQUIRK_NOLUNS|PQUIRK_NOSYNC}, 633 1.48 christos {{T_CDROM, T_REMOV, 634 1.157 bouyer "SONY ", "CD-ROM CDU-541 ", ""}, PQUIRK_NOLUNS}, 635 1.48 christos {{T_CDROM, T_REMOV, 636 1.157 bouyer "SONY ", "CD-ROM CDU-55S ", ""}, PQUIRK_NOLUNS}, 637 1.130 hwr {{T_CDROM, T_REMOV, 638 1.157 bouyer "SONY ", "CD-ROM CDU-561 ", ""}, PQUIRK_NOLUNS}, 639 1.186 bouyer {{T_CDROM, T_REMOV, 640 1.186 bouyer "SONY ", "CD-ROM CDU-76S", ""}, 641 1.186 bouyer PQUIRK_NOLUNS|PQUIRK_NOSYNC|PQUIRK_NOWIDE}, 642 1.48 christos {{T_CDROM, T_REMOV, 643 1.157 bouyer "SONY ", "CD-ROM CDU-8003A", ""}, PQUIRK_NOLUNS}, 644 1.48 christos {{T_CDROM, T_REMOV, 645 1.157 bouyer "SONY ", "CD-ROM CDU-8012 ", ""}, PQUIRK_NOLUNS}, 646 1.48 christos {{T_CDROM, T_REMOV, 647 1.157 bouyer "TEAC ", "CD-ROM ", "1.06"}, PQUIRK_NOLUNS}, 648 1.69 explorer {{T_CDROM, T_REMOV, 649 1.157 bouyer "TEAC ", "CD-ROM CD-56S ", "1.0B"}, PQUIRK_NOLUNS}, 650 1.48 christos {{T_CDROM, T_REMOV, 651 1.157 bouyer "TEXEL ", "CD-ROM ", "1.06"}, PQUIRK_NOLUNS}, 652 1.127 nathanw {{T_CDROM, T_REMOV, 653 1.157 bouyer "TEXEL ", "CD-ROM DM-XX24 K", "1.09"}, PQUIRK_NOLUNS}, 654 1.48 christos {{T_CDROM, T_REMOV, 655 1.157 bouyer "TEXEL ", "CD-ROM DM-XX24 K", "1.10"}, PQUIRK_NOLUNS}, 656 1.89 pk {{T_CDROM, T_REMOV, 657 1.198 bouyer "TOSHIBA ", "XM-4101TASUNSLCD", ""}, PQUIRK_NOLUNS|PQUIRK_NOSYNC}, 658 1.158 pk /* "IBM CDRM00201 !F" 0724 is an IBM OEM Toshiba XM-4101BME */ 659 1.158 pk {{T_CDROM, T_REMOV, 660 1.158 pk "IBM ", "CDRM00201 !F", "0724"}, PQUIRK_NOLUNS|PQUIRK_NOSYNC}, 661 1.92 enami {{T_CDROM, T_REMOV, 662 1.167 tsutsui "ShinaKen", "CD-ROM DM-3x1S", "1.04"}, PQUIRK_NOLUNS}, 663 1.98 explorer {{T_CDROM, T_REMOV, 664 1.157 bouyer "JVC ", "R2626", ""}, PQUIRK_NOLUNS}, 665 1.137 sjg {{T_CDROM, T_REMOV, 666 1.157 bouyer "YAMAHA", "CRW8424S", ""}, PQUIRK_NOLUNS}, 667 1.156 fvdl {{T_CDROM, T_REMOV, 668 1.195 jdolecek "NEC ", "CD-ROM DRIVE:222", ""}, PQUIRK_NOLUNS|PQUIRK_NOSYNC}, 669 1.156 fvdl 670 1.80 pk {{T_DIRECT, T_FIXED, 671 1.157 bouyer "MICROP ", "1588-15MBSUN0669", ""}, PQUIRK_AUTOSAVE}, 672 1.110 thorpej {{T_DIRECT, T_FIXED, 673 1.157 bouyer "MICROP ", "2217-15MQ1091501", ""}, PQUIRK_NOSYNCCACHE}, 674 1.55 scottr {{T_OPTICAL, T_REMOV, 675 1.157 bouyer "EPSON ", "OMD-5010 ", "3.08"}, PQUIRK_NOLUNS}, 676 1.129 hwr {{T_DIRECT, T_FIXED, 677 1.157 bouyer "ADAPTEC ", "AEC-4412BD", "1.2A"}, PQUIRK_NOMODESENSE}, 678 1.50 mycroft {{T_DIRECT, T_FIXED, 679 1.171 fredette "ADAPTEC ", "ACB-4000", ""}, PQUIRK_FORCELUNS|PQUIRK_AUTOSAVE|PQUIRK_NOMODESENSE}, 680 1.171 fredette {{T_DIRECT, T_FIXED, 681 1.157 bouyer "DEC ", "RZ55 (C) DEC", ""}, PQUIRK_AUTOSAVE}, 682 1.48 christos {{T_DIRECT, T_FIXED, 683 1.167 tsutsui "EMULEX ", "MD21/S2 ESDI", "A00"}, 684 1.167 tsutsui PQUIRK_FORCELUNS|PQUIRK_AUTOSAVE}, 685 1.162 christos {{T_DIRECT, T_FIXED, 686 1.167 tsutsui "MICROP", "1548-15MZ1077801", "HZ2P"}, PQUIRK_NOTAG}, 687 1.76 scottr {{T_DIRECT, T_FIXED, 688 1.157 bouyer "HP ", "C372", ""}, PQUIRK_NOTAG}, 689 1.108 mjacob {{T_DIRECT, T_FIXED, 690 1.157 bouyer "IBMRAID ", "0662S", ""}, PQUIRK_AUTOSAVE}, 691 1.76 scottr {{T_DIRECT, T_FIXED, 692 1.157 bouyer "IBM ", "0663H", ""}, PQUIRK_AUTOSAVE}, 693 1.82 thorpej {{T_DIRECT, T_FIXED, 694 1.157 bouyer "IBM", "0664", ""}, PQUIRK_AUTOSAVE}, 695 1.84 perry {{T_DIRECT, T_FIXED, 696 1.184 bouyer /* improperly report DT-only sync mode */ 697 1.184 bouyer "IBM ", "DXHS36D", ""}, 698 1.203 fvdl PQUIRK_CAP_SYNC|PQUIRK_CAP_WIDE16}, 699 1.203 fvdl {{T_DIRECT, T_FIXED, 700 1.203 fvdl "IBM ", "DXHS18Y", ""}, 701 1.184 bouyer PQUIRK_CAP_SYNC|PQUIRK_CAP_WIDE16}, 702 1.184 bouyer {{T_DIRECT, T_FIXED, 703 1.167 tsutsui "IBM ", "H3171-S2", ""}, 704 1.167 tsutsui PQUIRK_NOLUNS|PQUIRK_AUTOSAVE}, 705 1.96 scottr {{T_DIRECT, T_FIXED, 706 1.157 bouyer "IBM ", "KZ-C", ""}, PQUIRK_AUTOSAVE}, 707 1.81 thorpej /* Broken IBM disk */ 708 1.81 thorpej {{T_DIRECT, T_FIXED, 709 1.157 bouyer "" , "DFRSS2F", ""}, PQUIRK_AUTOSAVE}, 710 1.241 christos {{T_DIRECT, T_FIXED, 711 1.241 christos "Initio ", "", ""}, PQUIRK_NOBIGMODESENSE}, 712 1.282 christos {{T_DIRECT, T_FIXED, 713 1.282 christos "JMicron ", "Generic ", ""}, PQUIRK_NOFUA}, 714 1.87 mjacob {{T_DIRECT, T_REMOV, 715 1.157 bouyer "MPL ", "MC-DISK- ", ""}, PQUIRK_NOLUNS}, 716 1.48 christos {{T_DIRECT, T_FIXED, 717 1.157 bouyer "MAXTOR ", "XT-3280 ", ""}, PQUIRK_NOLUNS}, 718 1.48 christos {{T_DIRECT, T_FIXED, 719 1.157 bouyer "MAXTOR ", "XT-4380S ", ""}, PQUIRK_NOLUNS}, 720 1.48 christos {{T_DIRECT, T_FIXED, 721 1.157 bouyer "MAXTOR ", "MXT-1240S ", ""}, PQUIRK_NOLUNS}, 722 1.48 christos {{T_DIRECT, T_FIXED, 723 1.157 bouyer "MAXTOR ", "XT-4170S ", ""}, PQUIRK_NOLUNS}, 724 1.48 christos {{T_DIRECT, T_FIXED, 725 1.157 bouyer "MAXTOR ", "XT-8760S", ""}, PQUIRK_NOLUNS}, 726 1.48 christos {{T_DIRECT, T_FIXED, 727 1.157 bouyer "MAXTOR ", "LXT-213S ", ""}, PQUIRK_NOLUNS}, 728 1.48 christos {{T_DIRECT, T_FIXED, 729 1.157 bouyer "MAXTOR ", "LXT-213S SUN0207", ""}, PQUIRK_NOLUNS}, 730 1.52 thorpej {{T_DIRECT, T_FIXED, 731 1.157 bouyer "MAXTOR ", "LXT-200S ", ""}, PQUIRK_NOLUNS}, 732 1.48 christos {{T_DIRECT, T_FIXED, 733 1.157 bouyer "MEGADRV ", "EV1000", ""}, PQUIRK_NOMODESENSE}, 734 1.178 chs {{T_DIRECT, T_FIXED, 735 1.178 chs "MICROP", "1991-27MZ", ""}, PQUIRK_NOTAG}, 736 1.90 mjacob {{T_DIRECT, T_FIXED, 737 1.157 bouyer "MST ", "SnapLink ", ""}, PQUIRK_NOLUNS}, 738 1.54 hpeyerl {{T_DIRECT, T_FIXED, 739 1.157 bouyer "NEC ", "D3847 ", "0307"}, PQUIRK_NOLUNS}, 740 1.305 nat {{T_CDROM, T_REMOV, 741 1.305 nat "PiSCSI ", "SCSI CD-ROM ", ""}, PQUIRK_NOREADDISCINFO}, 742 1.96 scottr {{T_DIRECT, T_FIXED, 743 1.157 bouyer "QUANTUM ", "ELS85S ", ""}, PQUIRK_AUTOSAVE}, 744 1.48 christos {{T_DIRECT, T_FIXED, 745 1.157 bouyer "QUANTUM ", "LPS525S ", ""}, PQUIRK_NOLUNS}, 746 1.48 christos {{T_DIRECT, T_FIXED, 747 1.157 bouyer "QUANTUM ", "P105S 910-10-94x", ""}, PQUIRK_NOLUNS}, 748 1.48 christos {{T_DIRECT, T_FIXED, 749 1.157 bouyer "QUANTUM ", "PD1225S ", ""}, PQUIRK_NOLUNS}, 750 1.48 christos {{T_DIRECT, T_FIXED, 751 1.157 bouyer "QUANTUM ", "PD210S SUN0207", ""}, PQUIRK_NOLUNS}, 752 1.48 christos {{T_DIRECT, T_FIXED, 753 1.202 fvdl "QUANTUM ", "ATLAS IV 9 WLS", "0A0A"}, PQUIRK_CAP_NODT}, 754 1.202 fvdl {{T_DIRECT, T_FIXED, 755 1.157 bouyer "RODIME ", "RO3000S ", ""}, PQUIRK_NOLUNS}, 756 1.75 scottr {{T_DIRECT, T_FIXED, 757 1.157 bouyer "SEAGATE ", "ST125N ", ""}, PQUIRK_NOLUNS}, 758 1.48 christos {{T_DIRECT, T_FIXED, 759 1.157 bouyer "SEAGATE ", "ST157N ", ""}, PQUIRK_NOLUNS}, 760 1.48 christos {{T_DIRECT, T_FIXED, 761 1.157 bouyer "SEAGATE ", "ST296 ", ""}, PQUIRK_NOLUNS}, 762 1.48 christos {{T_DIRECT, T_FIXED, 763 1.157 bouyer "SEAGATE ", "ST296N ", ""}, PQUIRK_NOLUNS}, 764 1.204 fvdl {{T_DIRECT, T_FIXED, 765 1.204 fvdl "SEAGATE ", "ST318404LC ", ""}, PQUIRK_NOLUNS}, 766 1.163 mjl {{T_DIRECT, T_FIXED, 767 1.283 tsutsui "SEAGATE ", "ST336753LC ", ""}, PQUIRK_NOLUNS}, 768 1.283 tsutsui {{T_DIRECT, T_FIXED, 769 1.283 tsutsui "SEAGATE ", "ST336753LW ", ""}, PQUIRK_NOLUNS}, 770 1.283 tsutsui {{T_DIRECT, T_FIXED, 771 1.283 tsutsui "SEAGATE ", "ST336754LC ", ""}, PQUIRK_NOLUNS}, 772 1.283 tsutsui {{T_DIRECT, T_FIXED, 773 1.279 tsutsui "SEAGATE ", "ST39236LC ", ""}, PQUIRK_NOLUNS}, 774 1.279 tsutsui {{T_DIRECT, T_FIXED, 775 1.163 mjl "SEAGATE ", "ST15150N ", ""}, PQUIRK_NOTAG}, 776 1.86 mjacob {{T_DIRECT, T_FIXED, 777 1.157 bouyer "SEAGATE ", "ST19171", ""}, PQUIRK_NOMODESENSE}, 778 1.90 mjacob {{T_DIRECT, T_FIXED, 779 1.170 tsutsui "SEAGATE ", "ST32430N", ""}, PQUIRK_CAP_SYNC}, 780 1.170 tsutsui {{T_DIRECT, T_FIXED, 781 1.157 bouyer "SEAGATE ", "ST34501FC ", ""}, PQUIRK_NOMODESENSE}, 782 1.48 christos {{T_DIRECT, T_FIXED, 783 1.220 bouyer "SEAGATE ", "SX910800N", ""}, PQUIRK_NOTAG}, 784 1.220 bouyer {{T_DIRECT, T_FIXED, 785 1.157 bouyer "TOSHIBA ", "MK538FB ", "6027"}, PQUIRK_NOLUNS}, 786 1.197 pk {{T_DIRECT, T_FIXED, 787 1.197 pk "MICROP ", "1924", ""}, PQUIRK_CAP_SYNC}, 788 1.197 pk {{T_DIRECT, T_FIXED, 789 1.197 pk "FUJITSU ", "M2266", ""}, PQUIRK_CAP_SYNC}, 790 1.237 bjh21 {{T_DIRECT, T_FIXED, 791 1.237 bjh21 "FUJITSU ", "M2624S-512 ", ""}, PQUIRK_CAP_SYNC}, 792 1.242 bouyer {{T_DIRECT, T_FIXED, 793 1.242 bouyer "SEAGATE ", "SX336704LC" , ""}, PQUIRK_CAP_SYNC | PQUIRK_CAP_WIDE16}, 794 1.259 macallan {{T_DIRECT, T_FIXED, 795 1.259 macallan "SEAGATE ", "SX173404LC", ""}, PQUIRK_CAP_SYNC | PQUIRK_CAP_WIDE16}, 796 1.303 jmcneill {{T_DIRECT, T_FIXED, 797 1.303 jmcneill "ORACLE", "BlockVolume", ""}, PQUIRK_ONLYBIG}, 798 1.156 fvdl 799 1.58 christos {{T_DIRECT, T_REMOV, 800 1.259 macallan "IOMEGA", "ZIP 100", "J.03"}, PQUIRK_NOLUNS|PQUIRK_NOSYNC}, 801 1.168 soren {{T_DIRECT, T_REMOV, 802 1.212 mycroft "INSITE", "I325VM", ""}, PQUIRK_NOLUNS}, 803 1.18 mycroft 804 1.37 cgd /* XXX: QIC-36 tape behind Emulex adapter. Very broken. */ 805 1.48 christos {{T_SEQUENTIAL, T_REMOV, 806 1.157 bouyer " ", " ", " "}, PQUIRK_NOLUNS}, 807 1.171 fredette {{T_SEQUENTIAL, T_REMOV, 808 1.171 fredette "EMULEX ", "MT-02 QIC ", ""}, PQUIRK_NOLUNS}, 809 1.48 christos {{T_SEQUENTIAL, T_REMOV, 810 1.157 bouyer "CALIPER ", "CP150 ", ""}, PQUIRK_NOLUNS}, 811 1.48 christos {{T_SEQUENTIAL, T_REMOV, 812 1.157 bouyer "EXABYTE ", "EXB-8200 ", ""}, PQUIRK_NOLUNS}, 813 1.48 christos {{T_SEQUENTIAL, T_REMOV, 814 1.157 bouyer "SONY ", "GY-10C ", ""}, PQUIRK_NOLUNS}, 815 1.87 mjacob {{T_SEQUENTIAL, T_REMOV, 816 1.157 bouyer "SONY ", "SDT-2000 ", "2.09"}, PQUIRK_NOLUNS}, 817 1.48 christos {{T_SEQUENTIAL, T_REMOV, 818 1.157 bouyer "SONY ", "SDT-5000 ", "3."}, PQUIRK_NOSYNC|PQUIRK_NOWIDE}, 819 1.48 christos {{T_SEQUENTIAL, T_REMOV, 820 1.157 bouyer "SONY ", "SDT-5200 ", "3."}, PQUIRK_NOLUNS}, 821 1.48 christos {{T_SEQUENTIAL, T_REMOV, 822 1.157 bouyer "TANDBERG", " TDC 3600 ", ""}, PQUIRK_NOLUNS}, 823 1.47 pk /* Following entry reported as a Tandberg 3600; ref. PR1933 */ 824 1.48 christos {{T_SEQUENTIAL, T_REMOV, 825 1.157 bouyer "ARCHIVE ", "VIPER 150 21247", ""}, PQUIRK_NOLUNS}, 826 1.91 bouyer /* Following entry for a Cipher ST150S; ref. PR4171 */ 827 1.91 bouyer {{T_SEQUENTIAL, T_REMOV, 828 1.157 bouyer "ARCHIVE ", "VIPER 1500 21247", "2.2G"}, PQUIRK_NOLUNS}, 829 1.80 pk {{T_SEQUENTIAL, T_REMOV, 830 1.157 bouyer "ARCHIVE ", "Python 28454-XXX", ""}, PQUIRK_NOLUNS}, 831 1.48 christos {{T_SEQUENTIAL, T_REMOV, 832 1.157 bouyer "WANGTEK ", "5099ES SCSI", ""}, PQUIRK_NOLUNS}, 833 1.48 christos {{T_SEQUENTIAL, T_REMOV, 834 1.157 bouyer "WANGTEK ", "5150ES SCSI", ""}, PQUIRK_NOLUNS}, 835 1.125 hwr {{T_SEQUENTIAL, T_REMOV, 836 1.157 bouyer "WANGTEK ", "SCSI-36", ""}, PQUIRK_NOLUNS}, 837 1.48 christos {{T_SEQUENTIAL, T_REMOV, 838 1.157 bouyer "WangDAT ", "Model 1300 ", "02.4"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE}, 839 1.48 christos {{T_SEQUENTIAL, T_REMOV, 840 1.157 bouyer "WangDAT ", "Model 2600 ", "01.7"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE}, 841 1.48 christos {{T_SEQUENTIAL, T_REMOV, 842 1.157 bouyer "WangDAT ", "Model 3200 ", "02.2"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE}, 843 1.133 nisimura {{T_SEQUENTIAL, T_REMOV, 844 1.157 bouyer "TEAC ", "MT-2ST/N50 ", ""}, PQUIRK_NOLUNS}, 845 1.87 mjacob 846 1.101 bouyer {{T_SCANNER, T_FIXED, 847 1.157 bouyer "RICOH ", "IS60 ", "1R08"}, PQUIRK_NOLUNS}, 848 1.99 thorpej {{T_SCANNER, T_FIXED, 849 1.157 bouyer "UMAX ", "Astra 1200S ", "V2.9"}, PQUIRK_NOLUNS}, 850 1.102 fvdl {{T_SCANNER, T_FIXED, 851 1.157 bouyer "UMAX ", "Astra 1220S ", ""}, PQUIRK_NOLUNS}, 852 1.85 explorer {{T_SCANNER, T_FIXED, 853 1.157 bouyer "UMAX ", "UMAX S-6E ", "V2.0"}, PQUIRK_NOLUNS}, 854 1.95 mikel {{T_SCANNER, T_FIXED, 855 1.157 bouyer "UMAX ", "UMAX S-12 ", "V2.1"}, PQUIRK_NOLUNS}, 856 1.135 martin {{T_SCANNER, T_FIXED, 857 1.167 tsutsui "ULTIMA ", "A6000C ", ""}, PQUIRK_NOLUNS}, 858 1.150 mjacob {{T_PROCESSOR, T_FIXED, 859 1.249 hannken "ESG-SHV", "SCA HSBP M15", ""}, PQUIRK_NOLUNS}, 860 1.249 hannken {{T_PROCESSOR, T_FIXED, 861 1.167 tsutsui "SYMBIOS", "", ""}, PQUIRK_NOLUNS}, 862 1.87 mjacob {{T_PROCESSOR, T_FIXED, 863 1.157 bouyer "LITRONIC", "PCMCIA ", ""}, PQUIRK_NOLUNS}, 864 1.109 thorpej {{T_CHANGER, T_REMOV, 865 1.157 bouyer "SONY ", "CDL1100 ", ""}, PQUIRK_NOLUNS}, 866 1.119 mjacob {{T_ENCLOSURE, T_FIXED, 867 1.167 tsutsui "SUN ", "SENA ", ""}, PQUIRK_NOLUNS}, 868 1.304 palle {{T_CDROM, T_REMOV, 869 1.304 palle "SUN ", "Virtual CDROM ", ""}, PQUIRK_NOREADDISCINFO}, 870 1.18 mycroft }; 871 1.18 mycroft 872 1.12 mycroft /* 873 1.95 mikel * given a target and lun, ask the device what 874 1.12 mycroft * it is, and find the correct driver table 875 1.12 mycroft * entry. 876 1.12 mycroft */ 877 1.226 thorpej static int 878 1.226 thorpej scsi_probe_device(struct scsibus_softc *sc, int target, int lun) 879 1.18 mycroft { 880 1.157 bouyer struct scsipi_channel *chan = sc->sc_channel; 881 1.157 bouyer struct scsipi_periph *periph; 882 1.140 enami struct scsipi_inquiry_data inqbuf; 883 1.230 christos const struct scsi_quirk_inquiry_pattern *finger; 884 1.157 bouyer int checkdtype, priority, docontinue, quirks; 885 1.88 bouyer struct scsipibus_attach_args sa; 886 1.252 cegger cfdata_t cf; 887 1.231 drochner int locs[SCSIBUSCF_NLOCS]; 888 1.18 mycroft 889 1.119 mjacob /* 890 1.289 jakllsch * Assume no more LUNs to search after this one. 891 1.119 mjacob * If we successfully get Inquiry data and after 892 1.119 mjacob * merging quirks we find we can probe for more 893 1.289 jakllsch * LUNs, we will. 894 1.119 mjacob */ 895 1.119 mjacob docontinue = 0; 896 1.119 mjacob 897 1.18 mycroft /* Skip this slot if it is already attached. */ 898 1.157 bouyer if (scsipi_lookup_periph(chan, target, lun) != NULL) 899 1.119 mjacob return (docontinue); 900 1.18 mycroft 901 1.285 chs periph = scsipi_alloc_periph(M_WAITOK); 902 1.157 bouyer periph->periph_channel = chan; 903 1.157 bouyer periph->periph_switch = &scsi_probe_dev; 904 1.157 bouyer 905 1.157 bouyer periph->periph_target = target; 906 1.157 bouyer periph->periph_lun = lun; 907 1.157 bouyer periph->periph_quirks = chan->chan_defquirks; 908 1.157 bouyer 909 1.157 bouyer #ifdef SCSIPI_DEBUG 910 1.157 bouyer if (SCSIPI_DEBUG_TYPE == SCSIPI_BUSTYPE_SCSI && 911 1.157 bouyer SCSIPI_DEBUG_TARGET == target && 912 1.157 bouyer SCSIPI_DEBUG_LUN == lun) 913 1.157 bouyer periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS; 914 1.157 bouyer #endif 915 1.12 mycroft 916 1.12 mycroft /* 917 1.12 mycroft * Ask the device what it is 918 1.12 mycroft */ 919 1.18 mycroft 920 1.23 mycroft #ifdef SCSI_2_DEF 921 1.12 mycroft /* some devices need to be told to go to SCSI2 */ 922 1.12 mycroft /* However some just explode if you tell them this.. leave it out */ 923 1.157 bouyer scsi_change_def(periph, XS_CTL_DISCOVERY | XS_CTL_SILENT); 924 1.18 mycroft #endif /* SCSI_2_DEF */ 925 1.18 mycroft 926 1.18 mycroft /* Now go ask the device all about itself. */ 927 1.157 bouyer memset(&inqbuf, 0, sizeof(inqbuf)); 928 1.18 mycroft { 929 1.228 reinoud u_int8_t *extension = &inqbuf.flags1; 930 1.215 mycroft int len = 0; 931 1.20 mycroft while (len < 3) 932 1.141 dante extension[len++] = '\0'; 933 1.20 mycroft while (len < 3 + 28) 934 1.141 dante extension[len++] = ' '; 935 1.141 dante while (len < 3 + 28 + 20) 936 1.141 dante extension[len++] = '\0'; 937 1.141 dante while (len < 3 + 28 + 20 + 1) 938 1.141 dante extension[len++] = '\0'; 939 1.142 dante while (len < 3 + 28 + 20 + 1 + 1) 940 1.142 dante extension[len++] = '\0'; 941 1.142 dante while (len < 3 + 28 + 20 + 1 + 1 + (8*2)) 942 1.142 dante extension[len++] = ' '; 943 1.18 mycroft } 944 1.254 rmind if (scsipi_inquire(periph, &inqbuf, XS_CTL_DISCOVERY | XS_CTL_SILENT)) 945 1.215 mycroft goto bad; 946 1.18 mycroft 947 1.157 bouyer periph->periph_type = inqbuf.device & SID_TYPE; 948 1.157 bouyer if (inqbuf.dev_qual2 & SID_REMOVABLE) 949 1.157 bouyer periph->periph_flags |= PERIPH_REMOVABLE; 950 1.157 bouyer periph->periph_version = inqbuf.version & SID_ANSII; 951 1.12 mycroft 952 1.12 mycroft /* 953 1.12 mycroft * Any device qualifier that has the top bit set (qualifier&4 != 0) 954 1.12 mycroft * is vendor specific and won't match in this switch. 955 1.51 thorpej * All we do here is throw out bad/negative responses. 956 1.12 mycroft */ 957 1.51 thorpej checkdtype = 0; 958 1.18 mycroft switch (inqbuf.device & SID_QUAL) { 959 1.157 bouyer case SID_QUAL_LU_PRESENT: 960 1.51 thorpej checkdtype = 1; 961 1.2 deraadt break; 962 1.12 mycroft 963 1.217 mycroft case SID_QUAL_LU_NOTPRESENT: 964 1.157 bouyer case SID_QUAL_reserved: 965 1.157 bouyer case SID_QUAL_LU_NOT_SUPP: 966 1.18 mycroft goto bad; 967 1.12 mycroft 968 1.2 deraadt default: 969 1.2 deraadt break; 970 1.2 deraadt } 971 1.151 ad 972 1.289 jakllsch /* Let the adapter driver handle the device separately if it wants. */ 973 1.157 bouyer if (chan->chan_adapter->adapt_accesschk != NULL && 974 1.157 bouyer (*chan->chan_adapter->adapt_accesschk)(periph, &sa.sa_inqbuf)) 975 1.151 ad goto bad; 976 1.151 ad 977 1.149 mjacob if (checkdtype) { 978 1.157 bouyer switch (periph->periph_type) { 979 1.2 deraadt case T_DIRECT: 980 1.2 deraadt case T_SEQUENTIAL: 981 1.2 deraadt case T_PRINTER: 982 1.2 deraadt case T_PROCESSOR: 983 1.93 thorpej case T_WORM: 984 1.18 mycroft case T_CDROM: 985 1.2 deraadt case T_SCANNER: 986 1.2 deraadt case T_OPTICAL: 987 1.2 deraadt case T_CHANGER: 988 1.2 deraadt case T_COMM: 989 1.93 thorpej case T_IT8_1: 990 1.93 thorpej case T_IT8_2: 991 1.93 thorpej case T_STORARRAY: 992 1.93 thorpej case T_ENCLOSURE: 993 1.142 dante case T_SIMPLE_DIRECT: 994 1.142 dante case T_OPTIC_CARD_RW: 995 1.142 dante case T_OBJECT_STORED: 996 1.51 thorpej default: 997 1.2 deraadt break; 998 1.12 mycroft case T_NODEVICE: 999 1.18 mycroft goto bad; 1000 1.1 cgd } 1001 1.157 bouyer } 1002 1.157 bouyer 1003 1.157 bouyer sa.sa_periph = periph; 1004 1.157 bouyer sa.sa_inqbuf.type = inqbuf.device; 1005 1.157 bouyer sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ? 1006 1.157 bouyer T_REMOV : T_FIXED; 1007 1.157 bouyer sa.sa_inqbuf.vendor = inqbuf.vendor; 1008 1.157 bouyer sa.sa_inqbuf.product = inqbuf.product; 1009 1.157 bouyer sa.sa_inqbuf.revision = inqbuf.revision; 1010 1.157 bouyer sa.scsipi_info.scsi_version = inqbuf.version; 1011 1.157 bouyer sa.sa_inqptr = &inqbuf; 1012 1.157 bouyer 1013 1.230 christos finger = scsipi_inqmatch( 1014 1.230 christos &sa.sa_inqbuf, scsi_quirk_patterns, 1015 1.157 bouyer sizeof(scsi_quirk_patterns)/sizeof(scsi_quirk_patterns[0]), 1016 1.157 bouyer sizeof(scsi_quirk_patterns[0]), &priority); 1017 1.157 bouyer 1018 1.157 bouyer if (finger != NULL) 1019 1.157 bouyer quirks = finger->quirks; 1020 1.157 bouyer else 1021 1.157 bouyer quirks = 0; 1022 1.157 bouyer 1023 1.157 bouyer /* 1024 1.157 bouyer * Determine the operating mode capabilities of the device. 1025 1.157 bouyer */ 1026 1.157 bouyer if (periph->periph_version >= 2) { 1027 1.157 bouyer if ((inqbuf.flags3 & SID_CmdQue) != 0 && 1028 1.157 bouyer (quirks & PQUIRK_NOTAG) == 0) 1029 1.157 bouyer periph->periph_cap |= PERIPH_CAP_TQING; 1030 1.157 bouyer if ((inqbuf.flags3 & SID_Linked) != 0) 1031 1.157 bouyer periph->periph_cap |= PERIPH_CAP_LINKCMDS; 1032 1.157 bouyer if ((inqbuf.flags3 & SID_Sync) != 0 && 1033 1.157 bouyer (quirks & PQUIRK_NOSYNC) == 0) 1034 1.157 bouyer periph->periph_cap |= PERIPH_CAP_SYNC; 1035 1.157 bouyer if ((inqbuf.flags3 & SID_WBus16) != 0 && 1036 1.157 bouyer (quirks & PQUIRK_NOWIDE) == 0) 1037 1.157 bouyer periph->periph_cap |= PERIPH_CAP_WIDE16; 1038 1.157 bouyer if ((inqbuf.flags3 & SID_WBus32) != 0 && 1039 1.157 bouyer (quirks & PQUIRK_NOWIDE) == 0) 1040 1.157 bouyer periph->periph_cap |= PERIPH_CAP_WIDE32; 1041 1.157 bouyer if ((inqbuf.flags3 & SID_SftRe) != 0) 1042 1.157 bouyer periph->periph_cap |= PERIPH_CAP_SFTRESET; 1043 1.157 bouyer if ((inqbuf.flags3 & SID_RelAdr) != 0) 1044 1.157 bouyer periph->periph_cap |= PERIPH_CAP_RELADR; 1045 1.202 fvdl /* SPC-2 */ 1046 1.202 fvdl if (periph->periph_version >= 3 && 1047 1.202 fvdl !(quirks & PQUIRK_CAP_NODT)){ 1048 1.181 bouyer /* 1049 1.181 bouyer * Report ST clocking though CAP_WIDExx/CAP_SYNC. 1050 1.181 bouyer * If the device only supports DT, clear these 1051 1.181 bouyer * flags (DT implies SYNC and WIDE) 1052 1.181 bouyer */ 1053 1.181 bouyer switch (inqbuf.flags4 & SID_Clocking) { 1054 1.181 bouyer case SID_CLOCKING_DT_ONLY: 1055 1.181 bouyer periph->periph_cap &= 1056 1.181 bouyer ~(PERIPH_CAP_SYNC | 1057 1.181 bouyer PERIPH_CAP_WIDE16 | 1058 1.181 bouyer PERIPH_CAP_WIDE32); 1059 1.233 tsutsui /* FALLTHROUGH */ 1060 1.181 bouyer case SID_CLOCKING_SD_DT: 1061 1.181 bouyer periph->periph_cap |= PERIPH_CAP_DT; 1062 1.181 bouyer break; 1063 1.181 bouyer default: /* ST only or invalid */ 1064 1.181 bouyer /* nothing to do */ 1065 1.183 thorpej break; 1066 1.181 bouyer } 1067 1.202 fvdl } 1068 1.202 fvdl if (periph->periph_version >= 3) { 1069 1.181 bouyer if (inqbuf.flags4 & SID_IUS) 1070 1.181 bouyer periph->periph_cap |= PERIPH_CAP_IUS; 1071 1.181 bouyer if (inqbuf.flags4 & SID_QAS) 1072 1.181 bouyer periph->periph_cap |= PERIPH_CAP_QAS; 1073 1.181 bouyer } 1074 1.157 bouyer } 1075 1.184 bouyer if (quirks & PQUIRK_CAP_SYNC) 1076 1.184 bouyer periph->periph_cap |= PERIPH_CAP_SYNC; 1077 1.184 bouyer if (quirks & PQUIRK_CAP_WIDE16) 1078 1.184 bouyer periph->periph_cap |= PERIPH_CAP_WIDE16; 1079 1.157 bouyer 1080 1.157 bouyer /* 1081 1.157 bouyer * Now apply any quirks from the table. 1082 1.157 bouyer */ 1083 1.157 bouyer periph->periph_quirks |= quirks; 1084 1.157 bouyer if (periph->periph_version == 0 && 1085 1.157 bouyer (periph->periph_quirks & PQUIRK_FORCELUNS) == 0) 1086 1.157 bouyer periph->periph_quirks |= PQUIRK_NOLUNS; 1087 1.157 bouyer 1088 1.157 bouyer if ((periph->periph_quirks & PQUIRK_NOLUNS) == 0) 1089 1.157 bouyer docontinue = 1; 1090 1.157 bouyer 1091 1.231 drochner locs[SCSIBUSCF_TARGET] = target; 1092 1.231 drochner locs[SCSIBUSCF_LUN] = lun; 1093 1.225 drochner 1094 1.293 riastrad KERNEL_LOCK(1, NULL); 1095 1.291 thorpej if ((cf = config_search(sc->sc_dev, &sa, 1096 1.292 thorpej CFARGS(.submatch = config_stdsubmatch, 1097 1.292 thorpej .locators = locs))) != NULL) { 1098 1.157 bouyer scsipi_insert_periph(chan, periph); 1099 1.284 kardel 1100 1.284 kardel /* 1101 1.287 jdc * Determine supported opcodes and timeouts if available. 1102 1.287 jdc * Only do this on peripherals reporting SCSI version 3 1103 1.287 jdc * or greater - this command isn't in the SCSI-2 spec. and 1104 1.287 jdc * it causes either timeouts or peripherals disappearing 1105 1.287 jdc * when sent to some SCSI-1 or SCSI-2 peripherals. 1106 1.284 kardel */ 1107 1.287 jdc if (periph->periph_version >= 3) 1108 1.287 jdc scsipi_get_opcodeinfo(periph); 1109 1.284 kardel 1110 1.149 mjacob /* 1111 1.157 bouyer * XXX Can't assign periph_dev here, because we'll 1112 1.157 bouyer * XXX need it before config_attach() returns. Must 1113 1.157 bouyer * XXX assign it in periph driver. 1114 1.149 mjacob */ 1115 1.291 thorpej config_attach(sc->sc_dev, cf, &sa, scsibusprint, 1116 1.292 thorpej CFARGS(.locators = locs)); 1117 1.293 riastrad KERNEL_UNLOCK_ONE(NULL); 1118 1.51 thorpej } else { 1119 1.250 drochner scsibusprint(&sa, device_xname(sc->sc_dev)); 1120 1.205 thorpej aprint_normal(" not configured\n"); 1121 1.293 riastrad KERNEL_UNLOCK_ONE(NULL); 1122 1.18 mycroft goto bad; 1123 1.51 thorpej } 1124 1.18 mycroft 1125 1.119 mjacob return (docontinue); 1126 1.12 mycroft 1127 1.18 mycroft bad: 1128 1.276 mlelstv scsipi_free_periph(periph); 1129 1.119 mjacob return (docontinue); 1130 1.111 thorpej } 1131 1.111 thorpej 1132 1.111 thorpej /****** Entry points for user control of the SCSI bus. ******/ 1133 1.111 thorpej 1134 1.226 thorpej static int 1135 1.240 christos scsibusopen(dev_t dev, int flag, int fmt, 1136 1.240 christos struct lwp *l) 1137 1.111 thorpej { 1138 1.111 thorpej struct scsibus_softc *sc; 1139 1.117 thorpej int error, unit = minor(dev); 1140 1.111 thorpej 1141 1.248 tsutsui sc = device_lookup_private(&scsibus_cd, unit); 1142 1.248 tsutsui if (sc == NULL) 1143 1.111 thorpej return (ENXIO); 1144 1.111 thorpej 1145 1.114 thorpej if (sc->sc_flags & SCSIBUSF_OPEN) 1146 1.111 thorpej return (EBUSY); 1147 1.117 thorpej 1148 1.157 bouyer if ((error = scsipi_adapter_addref(sc->sc_channel->chan_adapter)) != 0) 1149 1.117 thorpej return (error); 1150 1.117 thorpej 1151 1.114 thorpej sc->sc_flags |= SCSIBUSF_OPEN; 1152 1.111 thorpej 1153 1.111 thorpej return (0); 1154 1.111 thorpej } 1155 1.111 thorpej 1156 1.226 thorpej static int 1157 1.240 christos scsibusclose(dev_t dev, int flag, int fmt, 1158 1.240 christos struct lwp *l) 1159 1.111 thorpej { 1160 1.248 tsutsui struct scsibus_softc *sc; 1161 1.117 thorpej 1162 1.248 tsutsui sc = device_lookup_private(&scsibus_cd, minor(dev)); 1163 1.157 bouyer scsipi_adapter_delref(sc->sc_channel->chan_adapter); 1164 1.111 thorpej 1165 1.114 thorpej sc->sc_flags &= ~SCSIBUSF_OPEN; 1166 1.111 thorpej 1167 1.111 thorpej return (0); 1168 1.111 thorpej } 1169 1.111 thorpej 1170 1.226 thorpej static int 1171 1.243 christos scsibusioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) 1172 1.111 thorpej { 1173 1.248 tsutsui struct scsibus_softc *sc; 1174 1.248 tsutsui struct scsipi_channel *chan; 1175 1.111 thorpej int error; 1176 1.111 thorpej 1177 1.248 tsutsui sc = device_lookup_private(&scsibus_cd, minor(dev)); 1178 1.248 tsutsui chan = sc->sc_channel; 1179 1.248 tsutsui 1180 1.113 thorpej /* 1181 1.113 thorpej * Enforce write permission for ioctls that change the 1182 1.113 thorpej * state of the bus. Host adapter specific ioctls must 1183 1.113 thorpej * be checked by the adapter driver. 1184 1.113 thorpej */ 1185 1.113 thorpej switch (cmd) { 1186 1.113 thorpej case SCBUSIOSCAN: 1187 1.159 bouyer case SCBUSIODETACH: 1188 1.113 thorpej case SCBUSIORESET: 1189 1.113 thorpej if ((flag & FWRITE) == 0) 1190 1.113 thorpej return (EBADF); 1191 1.113 thorpej } 1192 1.113 thorpej 1193 1.111 thorpej switch (cmd) { 1194 1.112 thorpej case SCBUSIOSCAN: 1195 1.112 thorpej { 1196 1.112 thorpej struct scbusioscan_args *a = 1197 1.112 thorpej (struct scbusioscan_args *)addr; 1198 1.112 thorpej 1199 1.157 bouyer error = scsi_probe_bus(sc, a->sa_target, a->sa_lun); 1200 1.112 thorpej break; 1201 1.112 thorpej } 1202 1.159 bouyer 1203 1.159 bouyer case SCBUSIODETACH: 1204 1.159 bouyer { 1205 1.159 bouyer struct scbusiodetach_args *a = 1206 1.159 bouyer (struct scbusiodetach_args *)addr; 1207 1.159 bouyer 1208 1.159 bouyer error = scsipi_target_detach(chan, a->sa_target, a->sa_lun, 0); 1209 1.159 bouyer break; 1210 1.159 bouyer } 1211 1.159 bouyer 1212 1.112 thorpej 1213 1.113 thorpej case SCBUSIORESET: 1214 1.113 thorpej /* FALLTHROUGH */ 1215 1.111 thorpej default: 1216 1.276 mlelstv error = scsipi_adapter_ioctl(chan, cmd, addr, flag, l->l_proc); 1217 1.113 thorpej break; 1218 1.111 thorpej } 1219 1.111 thorpej 1220 1.111 thorpej return (error); 1221 1.1 cgd } 1222