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 --- |