1 /*	$OpenBSD: umass_quirks.c,v 1.20 2005/06/02 02:03:33 krw Exp $	*/
2 /*	$NetBSD: umass_quirks.c,v 1.67 2004/06/28 07:49:16 mycroft Exp $	*/
3 
4 /*
5  * Copyright (c) 2001 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by MAEKAWA Masahide (gehenna@NetBSD.org).
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  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	  This product includes software developed by the NetBSD
22  *	  Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 #include <sys/buf.h>
44 
45 #if defined(__NetBSD__)
46 #include <dev/scsipi/scsipi_all.h> /* for scsiconf.h below */
47 #include <dev/scsipi/scsiconf.h> /* for quirks defines */
48 #elif defined(__OpenBSD__)
49 #include <scsi/scsi_all.h>
50 #include <scsi/scsiconf.h>
51 #endif
52 
53 #include <dev/usb/usb.h>
54 #include <dev/usb/usbdi.h>
55 #include <dev/usb/usbdevs.h>
56 
57 #include <dev/usb/umassvar.h>
58 #include <dev/usb/umass_quirks.h>
59 
60 Static usbd_status umass_init_insystem(struct umass_softc *);
61 Static usbd_status umass_init_shuttle(struct umass_softc *);
62 
63 Static void umass_fixup_sony(struct umass_softc *);
64 Static void umass_fixup_yedata(struct umass_softc *);
65 
66 Static const struct umass_quirk umass_quirks[] = {
67 	{ { USB_VENDOR_ATI, USB_PRODUCT_ATI2_205 },
68 	  UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
69 	  0,
70 	  0,
71 	  UMATCH_VENDOR_PRODUCT,
72 	  NULL, NULL
73 	},
74 
75 	{ { USB_VENDOR_DMI, USB_PRODUCT_DMI_SA2_0 },
76 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
77 	  0,
78 	  0,
79 	  UMATCH_VENDOR_PRODUCT,
80 	  NULL, NULL
81 	},
82 
83 	{ { USB_VENDOR_EASYDISK, USB_PRODUCT_EASYDISK_EASYDISK },
84 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
85 	  0,
86 	  0,
87 	  UMATCH_VENDOR_PRODUCT,
88 	  NULL, NULL
89 	},
90 
91 	{ { USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100 },
92 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
93 	  0,
94 	  PQUIRK_NOSENSE,
95 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
96 	  NULL, NULL
97 	},
98 
99 	{ { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB },
100 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
101 	  0,
102 	  0,
103 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
104 	  NULL, NULL
105 	},
106 
107 	{ { USB_VENDOR_HP, USB_PRODUCT_HP_CDWRITERPLUS },
108 	  UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI,
109 	  0,
110 	  PQUIRK_NOSENSE,
111 	  UMATCH_VENDOR_PRODUCT,
112 	  NULL, NULL
113 	},
114 
115 	{ { USB_VENDOR_IMATION, USB_PRODUCT_IMATION_FLASHGO },
116 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
117 	  0,
118 	  0,
119 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
120 	  NULL, NULL
121 	},
122 
123 	{ { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2 },
124 	  UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
125 	  0,
126 	  0,
127 	  UMATCH_VENDOR_PRODUCT,
128 	  NULL, NULL
129 	},
130 	{ { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI },
131 	  UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
132 	  0,
133 	  0,
134 	  UMATCH_VENDOR_PRODUCT,
135 	  NULL, NULL
136 	},
137 	{ { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5 },
138 	  UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
139 	  0,
140 	  0,
141 	  UMATCH_VENDOR_PRODUCT,
142 	  NULL, NULL
143 	},
144 
145 	{ { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_IDEUSB2 },
146 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
147 	  0,
148 	  0,
149 	  UMATCH_VENDOR_PRODUCT,
150 	  NULL, NULL
151 	},
152 
153 	{ { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE },
154 	  UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI,
155 	  0,
156 	  0,
157 	  UMATCH_VENDOR_PRODUCT,
158 	  umass_init_insystem, NULL
159 	},
160 
161 	{ { USB_VENDOR_IODATA2, USB_PRODUCT_IODATA2_USB2SC },
162 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
163 	  0,
164 	  0,
165 	  UMATCH_VENDOR_PRODUCT,
166 	  NULL, NULL
167 	},
168 
169 	{ { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100 },
170 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
171 	  0,
172 	  0,
173 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
174 	  NULL, NULL
175 	},
176 
177 	{ { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250 },
178 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
179 	  0,
180 	  0,
181 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
182 	  NULL, NULL
183 	},
184 
185 	{ { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250_2 },
186 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
187 	  0,
188 	  0,
189 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
190 	  NULL, NULL
191 	},
192 
193 	{ { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_1XX },
194 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
195 	  0,
196 	  PQUIRK_ONLYBIG,
197 	  UMATCH_VENDOR_PRODUCT,
198 	  NULL, NULL
199 	},
200 
201 	{ { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_3XX },
202 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
203 	  0,
204 	  0,
205 	  UMATCH_VENDOR_PRODUCT,
206 	  NULL, NULL
207 	},
208 
209 	{ { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG },
210 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
211 	  0,
212 	  0,
213 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
214 	  NULL, NULL
215 	},
216 
217 	{ { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM },
218 	  UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI,
219 	  0,
220 	  0,
221 	  UMATCH_VENDOR_PRODUCT,
222 	  NULL, NULL
223 	},
224 
225 	{ { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_S304 },
226 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
227 	  0,
228 	  0,
229 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
230 	  NULL, NULL
231 	},
232 
233 	{ { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_X },
234 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
235 	  0,
236 	  0,
237 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
238 	  NULL, NULL
239 	},
240 
241 	{ { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_DIMAGEA1 },
242 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
243 	  0,
244 	  0,
245 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
246 	  NULL, NULL
247 	},
248 
249 	{ { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY },
250 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
251 	  0,
252 	  0,
253 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
254 	  NULL, NULL
255 	},
256 
257 	{ { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2 },
258 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_ATAPI,
259 	  0,
260 	  0,
261 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
262 	  NULL, NULL
263 	},
264 
265 	{ { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3050 },
266 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
267 	  0,
268 	  0,
269 	  UMATCH_VENDOR_PRODUCT,
270 	  NULL, NULL
271 	},
272 
273 	{ { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND5010 },
274 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
275 	  0,
276 	  0,
277 	  UMATCH_VENDOR_PRODUCT,
278 	  NULL, NULL
279 	},
280 
281 	{ { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1 },
282 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
283 	  UMASS_QUIRK_WRONG_CSWSIG,
284 	  0,
285 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
286 	  NULL, NULL
287 	},
288 
289 	{ { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700 },
290 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
291 	  0,
292 	  PQUIRK_ONLYBIG | SDEV_NOSYNCCACHE,
293 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
294 	  NULL, NULL
295 	},
296 
297 	{ { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD1II },
298 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
299 	  0,
300 	  0,
301 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
302 	  NULL, NULL
303 	},
304 
305 	{ { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD2 },
306 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
307 	  0,
308 	  0,
309 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
310 	  NULL, NULL
311 	},
312 
313 	{ { USB_VENDOR_OTI, USB_PRODUCT_OTI_SOLID },
314 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
315 	  0,
316 	  0,
317 	  UMATCH_VENDOR_PRODUCT,
318 	  NULL, NULL
319 	},
320 
321 	{ { USB_VENDOR_PEN, USB_PRODUCT_PEN_MOBILEDRIVE },
322 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
323 	  0,
324 	  0,
325 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
326 	  NULL, NULL
327 	},
328 
329 	{ { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBDISK },
330 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
331 	  0,
332 	  0,
333 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
334 	  NULL, NULL
335 	},
336 
337 	{ { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBREADER },
338 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
339 	  0,
340 	  0,
341 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
342 	  NULL, NULL
343 	},
344 
345 	{ { USB_VENDOR_PILOTECH, USB_PRODUCT_PILOTECH_CRW600 },
346 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
347 	  0,
348 	  0,
349 	  UMATCH_VENDOR_PRODUCT,
350 	  NULL, NULL
351 	},
352 
353 	{ { USB_VENDOR_PQI, USB_PRODUCT_PQI_TRAVELFLASH },
354 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
355 	  0,
356 	  0,
357 	  UMATCH_VENDOR_PRODUCT,
358 	  NULL, NULL
359 	},
360 
361 	{ { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R },
362 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI,
363 	  UMASS_QUIRK_WRONG_CSWTAG,
364 	  0,
365 	  UMATCH_VENDOR_PRODUCT,
366 	  NULL, NULL
367 	},
368 
369 	{ { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB },
370 	  UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI,
371 	  0,
372 	  PQUIRK_NOSENSE,
373 	  UMATCH_VENDOR_PRODUCT,
374 	  umass_init_shuttle, NULL
375 	},
376 
377 	{ { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC },
378 	  UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI,
379 	  0,
380 	  0,
381 	  UMATCH_VENDOR_PRODUCT,
382 	  NULL, NULL
383 	},
384 
385 	{ { USB_VENDOR_SIIG, USB_PRODUCT_SIIG_MULTICARDREADER },
386 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
387 	  0,
388 	  0,
389 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
390 	  NULL,NULL
391 	},
392 
393 	{ { USB_VENDOR_SONY, USB_PRODUCT_SONY_DRIVEV2 },
394 	  UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
395 	  0,
396 	  0,
397 	  UMATCH_VENDOR_PRODUCT,
398 	  NULL, NULL
399 	},
400 
401 	{ { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC },
402 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
403 	  0,
404 	  0,
405 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
406 	  NULL, umass_fixup_sony
407 	},
408 
409 	{ { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC },
410 	  UMASS_WPROTO_CBI, UMASS_CPROTO_UFI,
411 	  0,
412 	  0,
413 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
414 	  NULL, NULL
415 	},
416 
417 	{ { USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB },
418 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
419 	  0,
420 	  0,
421 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
422 	  NULL, NULL
423 	},
424 
425 	{ { USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB },
426 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
427 	  0,
428 	  0,
429 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
430 	  NULL, NULL
431 	},
432 
433 	{ { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_XXX1100 },
434 	  UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI,
435 	  0,
436 	  0,
437 	  UMATCH_VENDOR_PRODUCT,
438 	  NULL, NULL
439 	},
440 
441 	{ { USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO },
442 	  UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI,
443 	  0,
444 	  0,
445 	  UMATCH_VENDOR_PRODUCT,
446 	  NULL, NULL
447 	},
448 
449 	{ { USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU },
450 	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI,
451 	  0,
452 	  0,
453 	  UMATCH_VENDOR_PRODUCT_REV,
454 	  NULL, umass_fixup_yedata
455 	},
456 
457 	{ { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_DNSSF7X},
458 	 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
459 	 0,
460 	 SDEV_NOSYNCCACHE,
461 	 UMATCH_VENDOR_PRODUCT,
462 	 NULL, NULL
463 	},
464 
465 	{ { USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD},
466 	 UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
467 	 0,
468 	 SDEV_NOSYNCCACHE,
469 	 UMATCH_VENDOR_PRODUCT,
470 	 NULL, NULL
471 	},
472 };
473 
474 const struct umass_quirk *
umass_lookup(u_int16_t vendor,u_int16_t product)475 umass_lookup(u_int16_t vendor, u_int16_t product)
476 {
477 	return ((const struct umass_quirk *)
478 		usb_lookup(umass_quirks, vendor, product));
479 }
480 
481 Static usbd_status
umass_init_insystem(struct umass_softc * sc)482 umass_init_insystem(struct umass_softc *sc)
483 {
484 	usbd_status err;
485 
486 	err = usbd_set_interface(sc->sc_iface, 1);
487 	if (err) {
488 		DPRINTF(UDMASS_USB,
489 			("%s: could not switch to Alt Interface 1\n",
490 			USBDEVNAME(sc->sc_dev)));
491 		return (err);
492 	}
493 
494 	return (USBD_NORMAL_COMPLETION);
495 }
496 
497 Static usbd_status
umass_init_shuttle(struct umass_softc * sc)498 umass_init_shuttle(struct umass_softc *sc)
499 {
500 	usb_device_request_t req;
501 	u_int8_t status[2];
502 
503 	/* The Linux driver does this */
504 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
505 	req.bRequest = 1;
506 	USETW(req.wValue, 0);
507 	USETW(req.wIndex, sc->sc_ifaceno);
508 	USETW(req.wLength, sizeof(status));
509 
510 	return (usbd_do_request(sc->sc_udev, &req, &status));
511 }
512 
513 Static void
umass_fixup_sony(struct umass_softc * sc)514 umass_fixup_sony(struct umass_softc *sc)
515 {
516 	usb_interface_descriptor_t *id;
517 
518 	id = usbd_get_interface_descriptor(sc->sc_iface);
519 	if (id->bInterfaceSubClass == 0xff)
520 		sc->sc_cmd = UMASS_CPROTO_SCSI;
521 }
522 
523 Static void
umass_fixup_yedata(struct umass_softc * sc)524 umass_fixup_yedata(struct umass_softc *sc)
525 {
526 	usb_device_descriptor_t *dd;
527 
528 	dd = usbd_get_device_descriptor(sc->sc_udev);
529 
530 	/*
531 	 * Revisions < 1.28 do not handle the interrupt endpoint very well.
532 	 */
533 	if (UGETW(dd->bcdDevice) < 0x128)
534 		sc->sc_wire = UMASS_WPROTO_CBI;
535 	else
536 		sc->sc_wire = UMASS_WPROTO_CBI_I;
537 }
538