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