Deleted Added
full compact
usb_msctest.c (194228) usb_msctest.c (194677)
1/* $FreeBSD: head/sys/dev/usb/usb_msctest.c 194228 2009-06-15 01:02:43Z thompsa $ */
1/* $FreeBSD: head/sys/dev/usb/usb_msctest.c 194677 2009-06-23 02:19:59Z thompsa $ */
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

27/*
28 * The following file contains code that will detect USB autoinstall
29 * disks.
30 *
31 * TODO: Potentially we could add code to automatically detect USB
32 * mass storage quirks for not supported SCSI commands!
33 */
34
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

27/*
28 * The following file contains code that will detect USB autoinstall
29 * disks.
30 *
31 * TODO: Potentially we could add code to automatically detect USB
32 * mass storage quirks for not supported SCSI commands!
33 */
34
35#include <dev/usb/usb_mfunc.h>
36#include <dev/usb/usb_error.h>
35#include <sys/stdint.h>
36#include <sys/stddef.h>
37#include <sys/param.h>
38#include <sys/queue.h>
39#include <sys/types.h>
40#include <sys/systm.h>
41#include <sys/kernel.h>
42#include <sys/bus.h>
43#include <sys/linker_set.h>
44#include <sys/module.h>
45#include <sys/lock.h>
46#include <sys/mutex.h>
47#include <sys/condvar.h>
48#include <sys/sysctl.h>
49#include <sys/sx.h>
50#include <sys/unistd.h>
51#include <sys/callout.h>
52#include <sys/malloc.h>
53#include <sys/priv.h>
54
37#include <dev/usb/usb.h>
55#include <dev/usb/usb.h>
56#include <dev/usb/usbdi.h>
57#include <dev/usb/usbdi_util.h>
38
39#define USB_DEBUG_VAR usb_debug
40
58
59#define USB_DEBUG_VAR usb_debug
60
41#include <dev/usb/usb_core.h>
42#include <dev/usb/usb_busdma.h>
43#include <dev/usb/usb_process.h>
44#include <dev/usb/usb_transfer.h>
45#include <dev/usb/usb_msctest.h>
46#include <dev/usb/usb_debug.h>
47#include <dev/usb/usb_busdma.h>
48#include <dev/usb/usb_device.h>
49#include <dev/usb/usb_request.h>
50#include <dev/usb/usb_util.h>
61#include <dev/usb/usb_busdma.h>
62#include <dev/usb/usb_process.h>
63#include <dev/usb/usb_transfer.h>
64#include <dev/usb/usb_msctest.h>
65#include <dev/usb/usb_debug.h>
66#include <dev/usb/usb_busdma.h>
67#include <dev/usb/usb_device.h>
68#include <dev/usb/usb_request.h>
69#include <dev/usb/usb_util.h>
51#include <dev/usb/usb_lookup.h>
52
70
53#include <dev/usb/usb_mfunc.h>
54#include <dev/usb/usb_error.h>
55#include <dev/usb/usb.h>
56
57enum {
58 ST_COMMAND,
59 ST_DATA_RD,
60 ST_DATA_RD_CS,
61 ST_DATA_WR,
62 ST_DATA_WR_CS,

--- 160 unchanged lines hidden (view full) ---

223 sc->state = xfer_index;
224 usbd_transfer_start(sc->xfer[xfer_index]);
225}
226
227static void
228bbb_data_clear_stall_callback(struct usb_xfer *xfer,
229 uint8_t next_xfer, uint8_t stall_xfer)
230{
71#include <dev/usb/usb.h>
72
73enum {
74 ST_COMMAND,
75 ST_DATA_RD,
76 ST_DATA_RD_CS,
77 ST_DATA_WR,
78 ST_DATA_WR_CS,

--- 160 unchanged lines hidden (view full) ---

239 sc->state = xfer_index;
240 usbd_transfer_start(sc->xfer[xfer_index]);
241}
242
243static void
244bbb_data_clear_stall_callback(struct usb_xfer *xfer,
245 uint8_t next_xfer, uint8_t stall_xfer)
246{
231 struct bbb_transfer *sc = xfer->priv_sc;
247 struct bbb_transfer *sc = usbd_xfer_softc(xfer);
232
233 if (usbd_clear_stall_callback(xfer, sc->xfer[stall_xfer])) {
234 switch (USB_GET_STATE(xfer)) {
235 case USB_ST_SETUP:
236 case USB_ST_TRANSFERRED:
237 bbb_transfer_start(sc, next_xfer);
238 break;
239 default:
240 bbb_done(sc, 1);
241 break;
242 }
243 }
244}
245
246static void
248
249 if (usbd_clear_stall_callback(xfer, sc->xfer[stall_xfer])) {
250 switch (USB_GET_STATE(xfer)) {
251 case USB_ST_SETUP:
252 case USB_ST_TRANSFERRED:
253 bbb_transfer_start(sc, next_xfer);
254 break;
255 default:
256 bbb_done(sc, 1);
257 break;
258 }
259 }
260}
261
262static void
247bbb_command_callback(struct usb_xfer *xfer)
263bbb_command_callback(struct usb_xfer *xfer, usb_error_t error)
248{
264{
249 struct bbb_transfer *sc = xfer->priv_sc;
265 struct bbb_transfer *sc = usbd_xfer_softc(xfer);
250 uint32_t tag;
251
252 switch (USB_GET_STATE(xfer)) {
253 case USB_ST_TRANSFERRED:
254 bbb_transfer_start
255 (sc, ((sc->dir == DIR_IN) ? ST_DATA_RD :
256 (sc->dir == DIR_OUT) ? ST_DATA_WR :
257 ST_STATUS));

--- 7 unchanged lines hidden (view full) ---

265 USETDW(sc->cbw.dCBWDataTransferLength, (uint32_t)sc->data_len);
266 sc->cbw.bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT);
267 sc->cbw.bCBWLUN = sc->lun;
268 sc->cbw.bCDBLength = sc->cmd_len;
269 if (sc->cbw.bCDBLength > sizeof(sc->cbw.CBWCDB)) {
270 sc->cbw.bCDBLength = sizeof(sc->cbw.CBWCDB);
271 DPRINTFN(0, "Truncating long command!\n");
272 }
266 uint32_t tag;
267
268 switch (USB_GET_STATE(xfer)) {
269 case USB_ST_TRANSFERRED:
270 bbb_transfer_start
271 (sc, ((sc->dir == DIR_IN) ? ST_DATA_RD :
272 (sc->dir == DIR_OUT) ? ST_DATA_WR :
273 ST_STATUS));

--- 7 unchanged lines hidden (view full) ---

281 USETDW(sc->cbw.dCBWDataTransferLength, (uint32_t)sc->data_len);
282 sc->cbw.bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT);
283 sc->cbw.bCBWLUN = sc->lun;
284 sc->cbw.bCDBLength = sc->cmd_len;
285 if (sc->cbw.bCDBLength > sizeof(sc->cbw.CBWCDB)) {
286 sc->cbw.bCDBLength = sizeof(sc->cbw.CBWCDB);
287 DPRINTFN(0, "Truncating long command!\n");
288 }
273 xfer->frlengths[0] = sizeof(sc->cbw);
274
275 usbd_set_frame_data(xfer, &sc->cbw, 0);
289 usbd_xfer_set_frame_data(xfer, 0, &sc->cbw, sizeof(sc->cbw));
276 usbd_transfer_submit(xfer);
277 break;
278
279 default: /* Error */
280 bbb_done(sc, 1);
281 break;
282 }
283}
284
285static void
290 usbd_transfer_submit(xfer);
291 break;
292
293 default: /* Error */
294 bbb_done(sc, 1);
295 break;
296 }
297}
298
299static void
286bbb_data_read_callback(struct usb_xfer *xfer)
300bbb_data_read_callback(struct usb_xfer *xfer, usb_error_t error)
287{
301{
288 struct bbb_transfer *sc = xfer->priv_sc;
289 usb_frlength_t max_bulk = xfer->max_data_length;
302 struct bbb_transfer *sc = usbd_xfer_softc(xfer);
303 usb_frlength_t max_bulk = usbd_xfer_max_len(xfer);
304 int actlen, sumlen;
290
305
306 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
307
291 switch (USB_GET_STATE(xfer)) {
292 case USB_ST_TRANSFERRED:
308 switch (USB_GET_STATE(xfer)) {
309 case USB_ST_TRANSFERRED:
293 sc->data_rem -= xfer->actlen;
294 sc->data_ptr += xfer->actlen;
295 sc->actlen += xfer->actlen;
310 sc->data_rem -= actlen;
311 sc->data_ptr += actlen;
312 sc->actlen += actlen;
296
313
297 if (xfer->actlen < xfer->sumlen) {
314 if (actlen < sumlen) {
298 /* short transfer */
299 sc->data_rem = 0;
300 }
301 case USB_ST_SETUP:
302 DPRINTF("max_bulk=%d, data_rem=%d\n",
303 max_bulk, sc->data_rem);
304
305 if (sc->data_rem == 0) {
306 bbb_transfer_start(sc, ST_STATUS);
307 break;
308 }
309 if (max_bulk > sc->data_rem) {
310 max_bulk = sc->data_rem;
311 }
315 /* short transfer */
316 sc->data_rem = 0;
317 }
318 case USB_ST_SETUP:
319 DPRINTF("max_bulk=%d, data_rem=%d\n",
320 max_bulk, sc->data_rem);
321
322 if (sc->data_rem == 0) {
323 bbb_transfer_start(sc, ST_STATUS);
324 break;
325 }
326 if (max_bulk > sc->data_rem) {
327 max_bulk = sc->data_rem;
328 }
312 xfer->timeout = sc->data_timeout;
313 xfer->frlengths[0] = max_bulk;
314
315 usbd_set_frame_data(xfer, sc->data_ptr, 0);
329 usbd_xfer_set_timeout(xfer, sc->data_timeout);
330 usbd_xfer_set_frame_data(xfer, 0, sc->data_ptr, max_bulk);
316 usbd_transfer_submit(xfer);
317 break;
318
319 default: /* Error */
331 usbd_transfer_submit(xfer);
332 break;
333
334 default: /* Error */
320 if (xfer->error == USB_ERR_CANCELLED) {
335 if (error == USB_ERR_CANCELLED) {
321 bbb_done(sc, 1);
322 } else {
323 bbb_transfer_start(sc, ST_DATA_RD_CS);
324 }
325 break;
326 }
327}
328
329static void
336 bbb_done(sc, 1);
337 } else {
338 bbb_transfer_start(sc, ST_DATA_RD_CS);
339 }
340 break;
341 }
342}
343
344static void
330bbb_data_rd_cs_callback(struct usb_xfer *xfer)
345bbb_data_rd_cs_callback(struct usb_xfer *xfer, usb_error_t error)
331{
332 bbb_data_clear_stall_callback(xfer, ST_STATUS,
333 ST_DATA_RD);
334}
335
336static void
346{
347 bbb_data_clear_stall_callback(xfer, ST_STATUS,
348 ST_DATA_RD);
349}
350
351static void
337bbb_data_write_callback(struct usb_xfer *xfer)
352bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error)
338{
353{
339 struct bbb_transfer *sc = xfer->priv_sc;
340 usb_frlength_t max_bulk = xfer->max_data_length;
354 struct bbb_transfer *sc = usbd_xfer_softc(xfer);
355 usb_frlength_t max_bulk = usbd_xfer_max_len(xfer);
356 int actlen, sumlen;
341
357
358 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
359
342 switch (USB_GET_STATE(xfer)) {
343 case USB_ST_TRANSFERRED:
360 switch (USB_GET_STATE(xfer)) {
361 case USB_ST_TRANSFERRED:
344 sc->data_rem -= xfer->actlen;
345 sc->data_ptr += xfer->actlen;
346 sc->actlen += xfer->actlen;
362 sc->data_rem -= actlen;
363 sc->data_ptr += actlen;
364 sc->actlen += actlen;
347
365
348 if (xfer->actlen < xfer->sumlen) {
366 if (actlen < sumlen) {
349 /* short transfer */
350 sc->data_rem = 0;
351 }
352 case USB_ST_SETUP:
353 DPRINTF("max_bulk=%d, data_rem=%d\n",
354 max_bulk, sc->data_rem);
355
356 if (sc->data_rem == 0) {
357 bbb_transfer_start(sc, ST_STATUS);
358 return;
359 }
360 if (max_bulk > sc->data_rem) {
361 max_bulk = sc->data_rem;
362 }
367 /* short transfer */
368 sc->data_rem = 0;
369 }
370 case USB_ST_SETUP:
371 DPRINTF("max_bulk=%d, data_rem=%d\n",
372 max_bulk, sc->data_rem);
373
374 if (sc->data_rem == 0) {
375 bbb_transfer_start(sc, ST_STATUS);
376 return;
377 }
378 if (max_bulk > sc->data_rem) {
379 max_bulk = sc->data_rem;
380 }
363 xfer->timeout = sc->data_timeout;
364 xfer->frlengths[0] = max_bulk;
365
366 usbd_set_frame_data(xfer, sc->data_ptr, 0);
381 usbd_xfer_set_timeout(xfer, sc->data_timeout);
382 usbd_xfer_set_frame_data(xfer, 0, sc->data_ptr, max_bulk);
367 usbd_transfer_submit(xfer);
368 return;
369
370 default: /* Error */
383 usbd_transfer_submit(xfer);
384 return;
385
386 default: /* Error */
371 if (xfer->error == USB_ERR_CANCELLED) {
387 if (error == USB_ERR_CANCELLED) {
372 bbb_done(sc, 1);
373 } else {
374 bbb_transfer_start(sc, ST_DATA_WR_CS);
375 }
376 return;
377
378 }
379}
380
381static void
388 bbb_done(sc, 1);
389 } else {
390 bbb_transfer_start(sc, ST_DATA_WR_CS);
391 }
392 return;
393
394 }
395}
396
397static void
382bbb_data_wr_cs_callback(struct usb_xfer *xfer)
398bbb_data_wr_cs_callback(struct usb_xfer *xfer, usb_error_t error)
383{
384 bbb_data_clear_stall_callback(xfer, ST_STATUS,
385 ST_DATA_WR);
386}
387
388static void
399{
400 bbb_data_clear_stall_callback(xfer, ST_STATUS,
401 ST_DATA_WR);
402}
403
404static void
389bbb_status_callback(struct usb_xfer *xfer)
405bbb_status_callback(struct usb_xfer *xfer, usb_error_t error)
390{
406{
391 struct bbb_transfer *sc = xfer->priv_sc;
407 struct bbb_transfer *sc = usbd_xfer_softc(xfer);
408 int actlen, sumlen;
392
409
410 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
411
393 switch (USB_GET_STATE(xfer)) {
394 case USB_ST_TRANSFERRED:
395
396 /* very simple status check */
397
412 switch (USB_GET_STATE(xfer)) {
413 case USB_ST_TRANSFERRED:
414
415 /* very simple status check */
416
398 if (xfer->actlen < sizeof(sc->csw)) {
417 if (actlen < sizeof(sc->csw)) {
399 bbb_done(sc, 1);/* error */
400 } else if (sc->csw.bCSWStatus == CSWSTATUS_GOOD) {
401 bbb_done(sc, 0);/* success */
402 } else {
403 bbb_done(sc, 1);/* error */
404 }
405 break;
406
407 case USB_ST_SETUP:
418 bbb_done(sc, 1);/* error */
419 } else if (sc->csw.bCSWStatus == CSWSTATUS_GOOD) {
420 bbb_done(sc, 0);/* success */
421 } else {
422 bbb_done(sc, 1);/* error */
423 }
424 break;
425
426 case USB_ST_SETUP:
408 xfer->frlengths[0] = sizeof(sc->csw);
409
410 usbd_set_frame_data(xfer, &sc->csw, 0);
427 usbd_xfer_set_frame_data(xfer, 0, &sc->csw, sizeof(sc->csw));
411 usbd_transfer_submit(xfer);
412 break;
413
414 default:
415 DPRINTFN(0, "Failed to read CSW: %s, try %d\n",
428 usbd_transfer_submit(xfer);
429 break;
430
431 default:
432 DPRINTFN(0, "Failed to read CSW: %s, try %d\n",
416 usbd_errstr(xfer->error), sc->status_try);
433 usbd_errstr(error), sc->status_try);
417
434
418 if ((xfer->error == USB_ERR_CANCELLED) ||
419 (sc->status_try)) {
435 if (error == USB_ERR_CANCELLED || sc->status_try) {
420 bbb_done(sc, 1);
421 } else {
422 sc->status_try = 1;
423 bbb_transfer_start(sc, ST_DATA_RD_CS);
424 }
425 break;
426 }
427}

--- 147 unchanged lines hidden ---
436 bbb_done(sc, 1);
437 } else {
438 sc->status_try = 1;
439 bbb_transfer_start(sc, ST_DATA_RD_CS);
440 }
441 break;
442 }
443}

--- 147 unchanged lines hidden ---