Sun May 23 08:42:32 2021 UTC ()
umass(4): Use an empty function callback, not null pointer.

This stupid bug, with an `XXX Broken!' comment right above, has been
preventing NetBSD from suspend/resume with a USB drive plugged in for
longer than I want to even think about admitting.  *sigh*


(riastradh)
diff -r1.67 -r1.68 src/sys/dev/usb/umass_scsipi.c

cvs diff -r1.67 -r1.68 src/sys/dev/usb/umass_scsipi.c (switch to unified diff)

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