xref: /netbsd/sys/dev/usb/umass_scsipi.c (revision 3bee0c11)
1 /*	$NetBSD: umass_scsipi.c,v 1.67 2021/04/24 23:36:59 thorpej Exp $	*/
2 
3 /*
4  * Copyright (c) 2001, 2003, 2012 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Lennart Augustsson (lennart@augustsson.net) at
9  * Carlstedt Research & Technology, Charles M. Hamnnum and Matthew R. Green.
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  *
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.
31  */
32 
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: umass_scsipi.c,v 1.67 2021/04/24 23:36:59 thorpej Exp $");
35 
36 #ifdef _KERNEL_OPT
37 #include "opt_usb.h"
38 #endif
39 
40 #include "atapibus.h"
41 #include "scsibus.h"
42 
43 #include <sys/param.h>
44 #include <sys/buf.h>
45 #include <sys/bufq.h>
46 #include <sys/conf.h>
47 #include <sys/device.h>
48 #include <sys/disk.h>		/* XXX */
49 #include <sys/ioctl.h>
50 #include <sys/kernel.h>
51 #include <sys/kmem.h>
52 #include <sys/lwp.h>
53 #include <sys/malloc.h>
54 #include <sys/systm.h>
55 
56 /* SCSI & ATAPI */
57 #include <sys/scsiio.h>
58 #include <dev/scsipi/scsi_spc.h>
59 #include <dev/scsipi/scsi_all.h>
60 #include <dev/scsipi/scsipi_all.h>
61 #include <dev/scsipi/scsiconf.h>
62 
63 #include <dev/scsipi/atapiconf.h>
64 
65 #include <dev/scsipi/scsipi_disk.h>
66 #include <dev/scsipi/scsi_disk.h>
67 #include <dev/scsipi/scsi_changer.h>
68 
69 #include <dev/scsipi/sdvar.h>	/* XXX */
70 
71 /* USB */
72 #include <dev/usb/usb.h>
73 #include <dev/usb/usbdi.h>
74 #include <dev/usb/usbdi_util.h>
75 #include <dev/usb/usbdevs.h>
76 #include <dev/usb/usbhist.h>
77 
78 #include <dev/usb/umassvar.h>
79 #include <dev/usb/umass_scsipi.h>
80 
81 struct umass_scsipi_softc {
82 	struct umassbus_softc	base;
83 
84 	struct atapi_adapter	sc_atapi_adapter;
85 #define sc_adapter sc_atapi_adapter._generic
86 	struct scsipi_channel sc_channel;
87 	usbd_status		sc_sync_status;
88 	struct scsi_request_sense	sc_sense_cmd;
89 };
90 
91 
92 #define SHORT_INQUIRY_LENGTH    36 /* XXX */
93 
94 #define UMASS_ATAPI_DRIVE	0
95 
96 Static void umass_scsipi_request(struct scsipi_channel *,
97 				 scsipi_adapter_req_t, void *);
98 Static void umass_scsipi_minphys(struct buf *);
99 Static int umass_scsipi_ioctl(struct scsipi_channel *, u_long,
100 			      void *, int, proc_t *);
101 Static int umass_scsipi_getgeom(struct scsipi_periph *,
102 				struct disk_parms *, u_long);
103 
104 Static void umass_scsipi_cb(struct umass_softc *, void *,
105 			    int, int);
106 Static void umass_scsipi_sense_cb(struct umass_softc *, void *,
107 				  int, int);
108 
109 Static struct umass_scsipi_softc *umass_scsipi_setup(struct umass_softc *);
110 
111 #if NATAPIBUS > 0
112 Static void umass_atapi_probe_device(struct atapibus_softc *, int);
113 
114 const struct scsipi_bustype umass_atapi_bustype = {
115 	.bustype_type = SCSIPI_BUSTYPE_ATAPI,
116 	.bustype_cmd = atapi_scsipi_cmd,
117 	.bustype_interpret_sense = atapi_interpret_sense,
118 	.bustype_printaddr = atapi_print_addr,
119 	.bustype_kill_pending = scsi_kill_pending,
120 	.bustype_async_event_xfer_mode = NULL,
121 };
122 #endif
123 
124 
125 #if NSCSIBUS > 0
126 int
127 umass_scsi_attach(struct umass_softc *sc)
128 {
129 	UMASSHIST_FUNC(); UMASSHIST_CALLED();
130 	struct umass_scsipi_softc *scbus;
131 
132 	scbus = umass_scsipi_setup(sc);
133 
134 	scbus->sc_channel.chan_bustype = &scsi_bustype;
135 	scbus->sc_channel.chan_ntargets = 2;
136 	scbus->sc_channel.chan_nluns = sc->maxlun + 1;
137 	scbus->sc_channel.chan_id = scbus->sc_channel.chan_ntargets - 1;
138 	DPRINTFM(UDMASS_USB, "sc %#jx: SCSI", (uintptr_t)sc, 0, 0, 0);
139 
140 	mutex_enter(&sc->sc_lock);
141 	sc->sc_refcnt++;
142 	mutex_exit(&sc->sc_lock);
143 	scbus->base.sc_child =
144 	    config_found(sc->sc_dev, &scbus->sc_channel, scsiprint,
145 			 CFARG_IATTR, "scsi",
146 			 CFARG_EOL);
147 	mutex_enter(&sc->sc_lock);
148 	if (--sc->sc_refcnt < 0)
149 		cv_broadcast(&sc->sc_detach_cv);
150 	mutex_exit(&sc->sc_lock);
151 
152 
153 	return 0;
154 }
155 
156 void
157 umass_scsi_detach(struct umass_softc *sc)
158 {
159 	struct umass_scsipi_softc *scbus = (struct umass_scsipi_softc *)sc->bus;
160 
161 	kmem_free(scbus, sizeof(*scbus));
162 	sc->bus = NULL;
163 }
164 #endif
165 
166 #if NATAPIBUS > 0
167 int
168 umass_atapi_attach(struct umass_softc *sc)
169 {
170 	UMASSHIST_FUNC(); UMASSHIST_CALLED();
171 	struct umass_scsipi_softc *scbus;
172 
173 	scbus = umass_scsipi_setup(sc);
174 	scbus->sc_atapi_adapter.atapi_probe_device =  umass_atapi_probe_device;
175 
176 	scbus->sc_channel.chan_bustype = &umass_atapi_bustype;
177 	scbus->sc_channel.chan_ntargets = 2;
178 	scbus->sc_channel.chan_nluns = 1;
179 
180 	scbus->sc_channel.chan_defquirks |= sc->sc_busquirks;
181 	DPRINTFM(UDMASS_USB, "sc %#jxp: ATAPI", (uintptr_t)sc, 0, 0, 0);
182 
183 	mutex_enter(&sc->sc_lock);
184 	sc->sc_refcnt++;
185 	mutex_exit(&sc->sc_lock);
186 	scbus->base.sc_child =
187 	    config_found(sc->sc_dev, &scbus->sc_channel, atapiprint,
188 			 CFARG_IATTR, "atapi",
189 			 CFARG_EOL);
190 	mutex_enter(&sc->sc_lock);
191 	if (--sc->sc_refcnt < 0)
192 		cv_broadcast(&sc->sc_detach_cv);
193 	mutex_exit(&sc->sc_lock);
194 
195 	return 0;
196 }
197 
198 void
199 umass_atapi_detach(struct umass_softc *sc)
200 {
201 	struct umass_scsipi_softc *scbus = (struct umass_scsipi_softc *)sc->bus;
202 
203 	kmem_free(scbus, sizeof(*scbus));
204 	sc->bus = NULL;
205 }
206 #endif
207 
208 Static struct umass_scsipi_softc *
209 umass_scsipi_setup(struct umass_softc *sc)
210 {
211 	struct umass_scsipi_softc *scbus;
212 
213 	scbus = kmem_zalloc(sizeof(*scbus), KM_SLEEP);
214 	sc->bus = &scbus->base;
215 
216 	/* Only use big commands for USB SCSI devices. */
217 	/* Do not ask for timeouts.  */
218 	sc->sc_busquirks |= PQUIRK_ONLYBIG|PQUIRK_NOREPSUPPOPC;
219 
220 	/* Fill in the adapter. */
221 	memset(&scbus->sc_adapter, 0, sizeof(scbus->sc_adapter));
222 	scbus->sc_adapter.adapt_dev = sc->sc_dev;
223 	scbus->sc_adapter.adapt_nchannels = 1;
224 	scbus->sc_adapter.adapt_request = umass_scsipi_request;
225 	scbus->sc_adapter.adapt_minphys = umass_scsipi_minphys;
226 	scbus->sc_adapter.adapt_ioctl = umass_scsipi_ioctl;
227 	scbus->sc_adapter.adapt_getgeom = umass_scsipi_getgeom;
228 	scbus->sc_adapter.adapt_flags = SCSIPI_ADAPT_MPSAFE;
229 
230 	/* Fill in the channel. */
231 	memset(&scbus->sc_channel, 0, sizeof(scbus->sc_channel));
232 	scbus->sc_channel.chan_adapter = &scbus->sc_adapter;
233 	scbus->sc_channel.chan_channel = 0;
234 	scbus->sc_channel.chan_flags = SCSIPI_CHAN_OPENINGS | SCSIPI_CHAN_NOSETTLE;
235 	scbus->sc_channel.chan_openings = 1;
236 	scbus->sc_channel.chan_max_periph = 1;
237 	scbus->sc_channel.chan_defquirks |= sc->sc_busquirks;
238 
239 	return scbus;
240 }
241 
242 Static void
243 umass_scsipi_request(struct scsipi_channel *chan,
244 		scsipi_adapter_req_t req, void *arg)
245 {
246 	UMASSHIST_FUNC(); UMASSHIST_CALLED();
247 	struct scsipi_adapter *adapt = chan->chan_adapter;
248 	struct scsipi_periph *periph;
249 	struct scsipi_xfer *xs;
250 	struct umass_softc *sc = device_private(adapt->adapt_dev);
251 	struct umass_scsipi_softc *scbus = (struct umass_scsipi_softc *)sc->bus;
252 	struct scsipi_generic *cmd;
253 	int cmdlen;
254 	int dir;
255 #ifdef UMASS_DEBUG
256 	microtime(&sc->tv);
257 #endif
258 	switch(req) {
259 	case ADAPTER_REQ_RUN_XFER:
260 		xs = arg;
261 		periph = xs->xs_periph;
262 		DIF(UDMASS_UPPER, periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS);
263 
264 		DPRINTFM(UDMASS_CMD, "sc %#jxp: %jd:%jd xs=%#jxp",
265 		    (uintptr_t)sc, periph->periph_target, periph->periph_lun,
266 		    (uintptr_t)xs);
267 		DPRINTFM(UDMASS_CMD, "cmd=0x%02jx datalen=%jd (quirks=%#jx, "
268 		    "poll=%jd)", xs->cmd->opcode, xs->datalen,
269 		    periph->periph_quirks, !!(xs->xs_control & XS_CTL_POLL));
270 #if defined(UMASS_DEBUG) && defined(SCSIPI_DEBUG)
271 		if (umassdebug & UDMASS_SCSI)
272 			show_scsipi_xs(xs);
273 		else if (umassdebug & ~UDMASS_CMD)
274 			show_scsipi_cmd(xs);
275 #endif
276 
277 		if (sc->sc_dying) {
278 			xs->error = XS_DRIVER_STUFFUP;
279 			goto done;
280 		}
281 
282 #ifdef UMASS_DEBUG
283 		if (SCSIPI_BUSTYPE_TYPE(chan->chan_bustype->bustype_type) ==
284 		    SCSIPI_BUSTYPE_ATAPI ?
285 		    periph->periph_target != UMASS_ATAPI_DRIVE :
286 		    periph->periph_target == chan->chan_id) {
287 			DPRINTFM(UDMASS_SCSI, "sc %#jx: wrong SCSI ID %jd",
288 			    (uintptr_t)sc, periph->periph_target, 0, 0);
289 			xs->error = XS_DRIVER_STUFFUP;
290 			goto done;
291 		}
292 #endif
293 
294 		cmd = xs->cmd;
295 		cmdlen = xs->cmdlen;
296 
297 		dir = DIR_NONE;
298 		if (xs->datalen) {
299 			switch (xs->xs_control &
300 			    (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) {
301 			case XS_CTL_DATA_IN:
302 				dir = DIR_IN;
303 				break;
304 			case XS_CTL_DATA_OUT:
305 				dir = DIR_OUT;
306 				break;
307 			}
308 		}
309 
310 		if (xs->datalen > UMASS_MAX_TRANSFER_SIZE) {
311 			printf("umass_cmd: large datalen, %d\n", xs->datalen);
312 			xs->error = XS_DRIVER_STUFFUP;
313 			goto done;
314 		}
315 
316 		if (xs->xs_control & XS_CTL_POLL) {
317 			/* Use sync transfer. XXX Broken! */
318 			DPRINTFM(UDMASS_SCSI, "sync dir=%jd\n", dir, 0, 0, 0);
319 			scbus->sc_sync_status = USBD_INVAL;
320 			sc->sc_methods->wire_xfer(sc, periph->periph_lun, cmd,
321 						  cmdlen, xs->data,
322 						  xs->datalen, dir,
323 						  xs->timeout, USBD_SYNCHRONOUS,
324 						  0, xs);
325 			DPRINTFM(UDMASS_SCSI, "done err=%jd",
326 			    scbus->sc_sync_status, 0, 0, 0);
327 			switch (scbus->sc_sync_status) {
328 			case USBD_NORMAL_COMPLETION:
329 				xs->error = XS_NOERROR;
330 				break;
331 			case USBD_TIMEOUT:
332 				xs->error = XS_TIMEOUT;
333 				break;
334 			default:
335 				xs->error = XS_DRIVER_STUFFUP;
336 				break;
337 			}
338 			goto done;
339 		} else {
340 			DPRINTFM(UDMASS_SCSI, "async dir=%jd, cmdlen=%jd"
341 			    " datalen=%jd", dir, cmdlen, xs->datalen, 0);
342 			sc->sc_methods->wire_xfer(sc, periph->periph_lun, cmd,
343 						  cmdlen, xs->data,
344 						  xs->datalen, dir,
345 						  xs->timeout, 0,
346 						  umass_scsipi_cb, xs);
347 			return;
348 		}
349 
350 		/* Return if command finishes early. */
351  done:
352 		scsipi_done(xs);
353 		return;
354 	default:
355 		/* Not supported, nothing to do. */
356 		;
357 	}
358 }
359 
360 Static void
361 umass_scsipi_minphys(struct buf *bp)
362 {
363 #ifdef DIAGNOSTIC
364 	if (bp->b_bcount <= 0) {
365 		printf("umass_scsipi_minphys count(%d) <= 0\n",
366 		       bp->b_bcount);
367 		bp->b_bcount = UMASS_MAX_TRANSFER_SIZE;
368 	}
369 #endif
370 	if (bp->b_bcount > UMASS_MAX_TRANSFER_SIZE)
371 		bp->b_bcount = UMASS_MAX_TRANSFER_SIZE;
372 	minphys(bp);
373 }
374 
375 int
376 umass_scsipi_ioctl(struct scsipi_channel *chan, u_long cmd,
377     void *arg, int flag, proc_t *p)
378 {
379 	/*struct umass_softc *sc = link->adapter_softc;*/
380 	/*struct umass_scsipi_softc *scbus = sc->bus;*/
381 
382 	switch (cmd) {
383 #if 0
384 	case SCBUSIORESET:
385 		ccb->ccb_h.status = CAM_REQ_INPROG;
386 		umass_reset(sc, umass_cam_cb, (void *) ccb);
387 		return 0;
388 #endif
389 	default:
390 		return ENOTTY;
391 	}
392 }
393 
394 Static int
395 umass_scsipi_getgeom(struct scsipi_periph *periph, struct disk_parms *dp,
396 		     u_long sectors)
397 {
398 	struct umass_softc *sc =
399 	    device_private(periph->periph_channel->chan_adapter->adapt_dev);
400 
401 	/* If it's not a floppy, we don't know what to do. */
402 	if (sc->sc_cmd != UMASS_CPROTO_UFI)
403 		return 0;
404 
405 	switch (sectors) {
406 	case 1440:
407 		/* Most likely a single density 3.5" floppy. */
408 		dp->heads = 2;
409 		dp->sectors = 9;
410 		dp->cyls = 80;
411 		return 1;
412 	case 2880:
413 		/* Most likely a double density 3.5" floppy. */
414 		dp->heads = 2;
415 		dp->sectors = 18;
416 		dp->cyls = 80;
417 		return 1;
418 	default:
419 		return 0;
420 	}
421 }
422 
423 Static void
424 umass_scsipi_cb(struct umass_softc *sc, void *priv, int residue, int status)
425 {
426 	UMASSHIST_FUNC(); UMASSHIST_CALLED();
427 	struct umass_scsipi_softc *scbus = (struct umass_scsipi_softc *)sc->bus;
428 	struct scsipi_xfer *xs = priv;
429 	struct scsipi_periph *periph = xs->xs_periph;
430 	int cmdlen, senselen;
431 #ifdef UMASS_DEBUG
432 	struct timeval tv;
433 	u_int delta;
434 	microtime(&tv);
435 	delta = (tv.tv_sec - sc->tv.tv_sec) * 1000000 + tv.tv_usec - sc->tv.tv_usec;
436 	DPRINTFM(UDMASS_CMD, "delta=%ju: xs=%#jx residue=%jd status=%jd",
437 	    delta, (uintptr_t)xs, residue, status);
438 #endif
439 
440 
441 	xs->resid = residue;
442 
443 	switch (status) {
444 	case STATUS_CMD_OK:
445 		xs->error = XS_NOERROR;
446 		break;
447 
448 	case STATUS_CMD_UNKNOWN:
449 		/* FALLTHROUGH */
450 	case STATUS_CMD_FAILED:
451 		/* fetch sense data */
452 		sc->sc_sense = 1;
453 		memset(&scbus->sc_sense_cmd, 0, sizeof(scbus->sc_sense_cmd));
454 		scbus->sc_sense_cmd.opcode = SCSI_REQUEST_SENSE;
455 		scbus->sc_sense_cmd.byte2 = periph->periph_lun <<
456 		    SCSI_CMD_LUN_SHIFT;
457 
458 		if (sc->sc_cmd == UMASS_CPROTO_UFI ||
459 		    sc->sc_cmd == UMASS_CPROTO_ATAPI)
460 			cmdlen = UFI_COMMAND_LENGTH;	/* XXX */
461 		else
462 			cmdlen = sizeof(scbus->sc_sense_cmd);
463 		if (periph->periph_version < 0x04) /* SPC-2 */
464 			senselen = 18;
465 		else
466 			senselen = sizeof(xs->sense);
467 		scbus->sc_sense_cmd.length = senselen;
468 		sc->sc_methods->wire_xfer(sc, periph->periph_lun,
469 					  &scbus->sc_sense_cmd, cmdlen,
470 					  &xs->sense, senselen,
471 					  DIR_IN, xs->timeout, 0,
472 					  umass_scsipi_sense_cb, xs);
473 		return;
474 
475 	case STATUS_WIRE_FAILED:
476 		xs->error = XS_RESET;
477 		break;
478 
479 	case STATUS_TIMEOUT:
480 		xs->error = XS_TIMEOUT;
481 		break;
482 
483 	default:
484 		panic("%s: Unknown status %d in umass_scsipi_cb",
485 			device_xname(sc->sc_dev), status);
486 	}
487 
488 	DPRINTFM(UDMASS_CMD, "return xs->error=%jd, xs->xs_status=%#jx"
489 	    " xs->resid=%jd", xs->error, xs->xs_status, xs->resid, 0);
490 
491 	scsipi_done(xs);
492 }
493 
494 /*
495  * Finalise a completed autosense operation
496  */
497 Static void
498 umass_scsipi_sense_cb(struct umass_softc *sc, void *priv, int residue,
499 		      int status)
500 {
501 	UMASSHIST_FUNC(); UMASSHIST_CALLED();
502 	struct scsipi_xfer *xs = priv;
503 	size_t extra;
504 
505 	DPRINTFM(UDMASS_CMD, "sc %#jx: xs=%#jx residue=%jd status=%jd",
506 	    (uintptr_t)sc, (uintptr_t)xs, residue, status);
507 
508 	sc->sc_sense = 0;
509 	switch (status) {
510 	case STATUS_CMD_OK:
511 	case STATUS_CMD_UNKNOWN:
512 		/* getting sense data succeeded */
513 		extra = sizeof(xs->sense.scsi_sense)
514 		      - sizeof(xs->sense.scsi_sense.extra_bytes);
515 		if (residue <= extra)
516 			xs->error = XS_SENSE;
517 		else
518 			xs->error = XS_SHORTSENSE;
519 		break;
520 	default:
521 		DPRINTFM(UDMASS_SCSI, "sc %#jx: Autosense failed, status %jd",
522 		    (uintptr_t)sc, status, 0, 0);
523 		xs->error = XS_DRIVER_STUFFUP;
524 		break;
525 	}
526 
527 	DPRINTFM(UDMASS_CMD, "return xs->error=%jd, xs->xs_status=%#jx"
528 	    " xs->resid=%jd", xs->error, xs->xs_status, xs->resid, 0);
529 
530 	scsipi_done(xs);
531 }
532 
533 #if NATAPIBUS > 0
534 Static void
535 umass_atapi_probe_device(struct atapibus_softc *atapi, int target)
536 {
537 	UMASSHIST_FUNC(); UMASSHIST_CALLED();
538 	struct scsipi_channel *chan = atapi->sc_channel;
539 	struct scsipi_periph *periph;
540 	struct scsipibus_attach_args sa;
541 	char vendor[33], product[65], revision[17];
542 	struct scsipi_inquiry_data inqbuf;
543 
544 	DPRINTFM(UDMASS_SCSI, "atapi=%#jx target=%jd", (uintptr_t)atapi,
545 	    target, 0, 0);
546 
547 	if (target != UMASS_ATAPI_DRIVE)	/* only probe drive 0 */
548 		return;
549 
550 	/* skip if already attached */
551 	if (scsipi_lookup_periph(chan, target, 0) != NULL) {
552 		return;
553 	}
554 
555 	periph = scsipi_alloc_periph(M_WAITOK);
556 	DIF(UDMASS_UPPER, periph->periph_dbflags |= 1); /* XXX 1 */
557 	periph->periph_channel = chan;
558 	periph->periph_switch = &atapi_probe_periphsw;
559 	periph->periph_target = target;
560 	periph->periph_quirks = chan->chan_defquirks;
561 
562 	DPRINTFM(UDMASS_SCSI, "doing inquiry", 0, 0, 0, 0);
563 	/* Now go ask the device all about itself. */
564 	memset(&inqbuf, 0, sizeof(inqbuf));
565 	if (scsipi_inquire(periph, &inqbuf, XS_CTL_DISCOVERY) != 0) {
566 		DPRINTFM(UDMASS_SCSI, "scsipi_inquire failed", 0, 0, 0, 0);
567 		free(periph, M_DEVBUF);
568 		return;
569 	}
570 
571 	strnvisx(vendor, sizeof(vendor), inqbuf.vendor, 8,
572 	    VIS_TRIM|VIS_SAFE|VIS_OCTAL);
573 	strnvisx(product, sizeof(product), inqbuf.product, 16,
574 	    VIS_TRIM|VIS_SAFE|VIS_OCTAL);
575 	strnvisx(revision, sizeof(revision), inqbuf.revision, 4,
576 	    VIS_TRIM|VIS_SAFE|VIS_OCTAL);
577 
578 	sa.sa_periph = periph;
579 	sa.sa_inqbuf.type = inqbuf.device;
580 	sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ?
581 	    T_REMOV : T_FIXED;
582 	if (sa.sa_inqbuf.removable)
583 		periph->periph_flags |= PERIPH_REMOVABLE;
584 	sa.sa_inqbuf.vendor = vendor;
585 	sa.sa_inqbuf.product = product;
586 	sa.sa_inqbuf.revision = revision;
587 	sa.sa_inqptr = NULL;
588 
589 	atapi_probe_device(atapi, target, periph, &sa);
590 	/* atapi_probe_device() frees the periph when there is no device.*/
591 }
592 #endif
593