Deleted Added
full compact
usb_msctest.c (242364) usb_msctest.c (244503)
1/* $FreeBSD: head/sys/dev/usb/usb_msctest.c 242364 2012-10-30 16:56:16Z hselasky $ */
1/* $FreeBSD: head/sys/dev/usb/usb_msctest.c 244503 2012-12-20 18:38:02Z hselasky $ */
2/*-
3 * Copyright (c) 2008,2011 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.

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

134#define CSWSTATUS_GOOD 0x0
135#define CSWSTATUS_FAILED 0x1
136#define CSWSTATUS_PHASE 0x2
137} __packed;
138
139struct bbb_transfer {
140 struct mtx mtx;
141 struct cv cv;
2/*-
3 * Copyright (c) 2008,2011 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.

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

134#define CSWSTATUS_GOOD 0x0
135#define CSWSTATUS_FAILED 0x1
136#define CSWSTATUS_PHASE 0x2
137} __packed;
138
139struct bbb_transfer {
140 struct mtx mtx;
141 struct cv cv;
142 struct bbb_cbw cbw;
143 struct bbb_csw csw;
142 struct bbb_cbw *cbw;
143 struct bbb_csw *csw;
144
145 struct usb_xfer *xfer[ST_MAX];
146
147 uint8_t *data_ptr;
148
149 usb_size_t data_len; /* bytes */
150 usb_size_t data_rem; /* bytes */
151 usb_timeout_t data_timeout; /* ms */
152 usb_frlength_t actlen; /* bytes */
153
154 uint8_t cmd_len; /* bytes */
155 uint8_t dir;
156 uint8_t lun;
157 uint8_t state;
158 uint8_t status_try;
159 int error;
160
144
145 struct usb_xfer *xfer[ST_MAX];
146
147 uint8_t *data_ptr;
148
149 usb_size_t data_len; /* bytes */
150 usb_size_t data_rem; /* bytes */
151 usb_timeout_t data_timeout; /* ms */
152 usb_frlength_t actlen; /* bytes */
153
154 uint8_t cmd_len; /* bytes */
155 uint8_t dir;
156 uint8_t lun;
157 uint8_t state;
158 uint8_t status_try;
159 int error;
160
161 uint8_t buffer[SCSI_MAX_LEN] __aligned(4);
161 uint8_t *buffer;
162};
163
164static usb_callback_t bbb_command_callback;
165static usb_callback_t bbb_data_read_callback;
166static usb_callback_t bbb_data_rd_cs_callback;
167static usb_callback_t bbb_data_write_callback;
168static usb_callback_t bbb_data_wr_cs_callback;
169static usb_callback_t bbb_status_callback;

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

179
180static const struct usb_config bbb_config[ST_MAX] = {
181
182 [ST_COMMAND] = {
183 .type = UE_BULK,
184 .endpoint = UE_ADDR_ANY,
185 .direction = UE_DIR_OUT,
186 .bufsize = sizeof(struct bbb_cbw),
162};
163
164static usb_callback_t bbb_command_callback;
165static usb_callback_t bbb_data_read_callback;
166static usb_callback_t bbb_data_rd_cs_callback;
167static usb_callback_t bbb_data_write_callback;
168static usb_callback_t bbb_data_wr_cs_callback;
169static usb_callback_t bbb_status_callback;

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

179
180static const struct usb_config bbb_config[ST_MAX] = {
181
182 [ST_COMMAND] = {
183 .type = UE_BULK,
184 .endpoint = UE_ADDR_ANY,
185 .direction = UE_DIR_OUT,
186 .bufsize = sizeof(struct bbb_cbw),
187 .flags = {.ext_buffer = 1,},
188 .callback = &bbb_command_callback,
189 .timeout = 4 * USB_MS_HZ, /* 4 seconds */
190 },
191
192 [ST_DATA_RD] = {
193 .type = UE_BULK,
194 .endpoint = UE_ADDR_ANY,
195 .direction = UE_DIR_IN,
187 .callback = &bbb_command_callback,
188 .timeout = 4 * USB_MS_HZ, /* 4 seconds */
189 },
190
191 [ST_DATA_RD] = {
192 .type = UE_BULK,
193 .endpoint = UE_ADDR_ANY,
194 .direction = UE_DIR_IN,
196 .bufsize = BULK_SIZE,
197 .flags = {.ext_buffer = 1,.proxy_buffer = 1,.short_xfer_ok = 1,},
195 .bufsize = MAX(SCSI_MAX_LEN, BULK_SIZE),
196 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
198 .callback = &bbb_data_read_callback,
199 .timeout = 4 * USB_MS_HZ, /* 4 seconds */
200 },
201
202 [ST_DATA_RD_CS] = {
203 .type = UE_CONTROL,
204 .endpoint = 0x00, /* Control pipe */
205 .direction = UE_DIR_ANY,

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

227 .timeout = 1 * USB_MS_HZ, /* 1 second */
228 },
229
230 [ST_STATUS] = {
231 .type = UE_BULK,
232 .endpoint = UE_ADDR_ANY,
233 .direction = UE_DIR_IN,
234 .bufsize = sizeof(struct bbb_csw),
197 .callback = &bbb_data_read_callback,
198 .timeout = 4 * USB_MS_HZ, /* 4 seconds */
199 },
200
201 [ST_DATA_RD_CS] = {
202 .type = UE_CONTROL,
203 .endpoint = 0x00, /* Control pipe */
204 .direction = UE_DIR_ANY,

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

226 .timeout = 1 * USB_MS_HZ, /* 1 second */
227 },
228
229 [ST_STATUS] = {
230 .type = UE_BULK,
231 .endpoint = UE_ADDR_ANY,
232 .direction = UE_DIR_IN,
233 .bufsize = sizeof(struct bbb_csw),
235 .flags = {.ext_buffer = 1,.short_xfer_ok = 1,},
234 .flags = {.short_xfer_ok = 1,},
236 .callback = &bbb_status_callback,
237 .timeout = 1 * USB_MS_HZ, /* 1 second */
238 },
239};
240
241static void
242bbb_done(struct bbb_transfer *sc, int error)
243{
235 .callback = &bbb_status_callback,
236 .timeout = 1 * USB_MS_HZ, /* 1 second */
237 },
238};
239
240static void
241bbb_done(struct bbb_transfer *sc, int error)
242{
244
245 sc->error = error;
246 sc->state = ST_COMMAND;
247 sc->status_try = 1;
248 cv_signal(&sc->cv);
249}
250
251static void
252bbb_transfer_start(struct bbb_transfer *sc, uint8_t xfer_index)

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

285 bbb_transfer_start
286 (sc, ((sc->dir == DIR_IN) ? ST_DATA_RD :
287 (sc->dir == DIR_OUT) ? ST_DATA_WR :
288 ST_STATUS));
289 break;
290
291 case USB_ST_SETUP:
292 sc->status_try = 0;
243 sc->error = error;
244 sc->state = ST_COMMAND;
245 sc->status_try = 1;
246 cv_signal(&sc->cv);
247}
248
249static void
250bbb_transfer_start(struct bbb_transfer *sc, uint8_t xfer_index)

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

283 bbb_transfer_start
284 (sc, ((sc->dir == DIR_IN) ? ST_DATA_RD :
285 (sc->dir == DIR_OUT) ? ST_DATA_WR :
286 ST_STATUS));
287 break;
288
289 case USB_ST_SETUP:
290 sc->status_try = 0;
293 tag = UGETDW(sc->cbw.dCBWTag) + 1;
294 USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE);
295 USETDW(sc->cbw.dCBWTag, tag);
296 USETDW(sc->cbw.dCBWDataTransferLength, (uint32_t)sc->data_len);
297 sc->cbw.bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT);
298 sc->cbw.bCBWLUN = sc->lun;
299 sc->cbw.bCDBLength = sc->cmd_len;
300 if (sc->cbw.bCDBLength > sizeof(sc->cbw.CBWCDB)) {
301 sc->cbw.bCDBLength = sizeof(sc->cbw.CBWCDB);
291 tag = UGETDW(sc->cbw->dCBWTag) + 1;
292 USETDW(sc->cbw->dCBWSignature, CBWSIGNATURE);
293 USETDW(sc->cbw->dCBWTag, tag);
294 USETDW(sc->cbw->dCBWDataTransferLength, (uint32_t)sc->data_len);
295 sc->cbw->bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT);
296 sc->cbw->bCBWLUN = sc->lun;
297 sc->cbw->bCDBLength = sc->cmd_len;
298 if (sc->cbw->bCDBLength > sizeof(sc->cbw->CBWCDB)) {
299 sc->cbw->bCDBLength = sizeof(sc->cbw->CBWCDB);
302 DPRINTFN(0, "Truncating long command\n");
303 }
300 DPRINTFN(0, "Truncating long command\n");
301 }
304 usbd_xfer_set_frame_data(xfer, 0, &sc->cbw, sizeof(sc->cbw));
305 usbd_transfer_submit(xfer);
306 break;
307
308 default: /* Error */
309 bbb_done(sc, error);
310 break;
311 }
312}

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

425
426 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
427
428 switch (USB_GET_STATE(xfer)) {
429 case USB_ST_TRANSFERRED:
430
431 /* very simple status check */
432
302 usbd_transfer_submit(xfer);
303 break;
304
305 default: /* Error */
306 bbb_done(sc, error);
307 break;
308 }
309}

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

422
423 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
424
425 switch (USB_GET_STATE(xfer)) {
426 case USB_ST_TRANSFERRED:
427
428 /* very simple status check */
429
433 if (actlen < (int)sizeof(sc->csw)) {
430 if (actlen < (int)sizeof(struct bbb_csw)) {
434 bbb_done(sc, USB_ERR_SHORT_XFER);
431 bbb_done(sc, USB_ERR_SHORT_XFER);
435 } else if (sc->csw.bCSWStatus == CSWSTATUS_GOOD) {
432 } else if (sc->csw->bCSWStatus == CSWSTATUS_GOOD) {
436 bbb_done(sc, 0); /* success */
437 } else {
438 bbb_done(sc, ERR_CSW_FAILED); /* error */
439 }
440 break;
441
442 case USB_ST_SETUP:
433 bbb_done(sc, 0); /* success */
434 } else {
435 bbb_done(sc, ERR_CSW_FAILED); /* error */
436 }
437 break;
438
439 case USB_ST_SETUP:
443 usbd_xfer_set_frame_data(xfer, 0, &sc->csw, sizeof(sc->csw));
444 usbd_transfer_submit(xfer);
445 break;
446
447 default:
448 DPRINTF("Failed to read CSW: %s, try %d\n",
449 usbd_errstr(error), sc->status_try);
450
451 if (error == USB_ERR_CANCELLED || sc->status_try) {

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

473 sc->lun = lun;
474 sc->dir = data_len ? dir : DIR_NONE;
475 sc->data_ptr = data_ptr;
476 sc->data_len = data_len;
477 sc->data_rem = data_len;
478 sc->data_timeout = (data_timeout + USB_MS_HZ);
479 sc->actlen = 0;
480 sc->cmd_len = cmd_len;
440 usbd_transfer_submit(xfer);
441 break;
442
443 default:
444 DPRINTF("Failed to read CSW: %s, try %d\n",
445 usbd_errstr(error), sc->status_try);
446
447 if (error == USB_ERR_CANCELLED || sc->status_try) {

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

469 sc->lun = lun;
470 sc->dir = data_len ? dir : DIR_NONE;
471 sc->data_ptr = data_ptr;
472 sc->data_len = data_len;
473 sc->data_rem = data_len;
474 sc->data_timeout = (data_timeout + USB_MS_HZ);
475 sc->actlen = 0;
476 sc->cmd_len = cmd_len;
481 memset(&sc->cbw.CBWCDB, 0, sizeof(sc->cbw.CBWCDB));
482 memcpy(&sc->cbw.CBWCDB, cmd_ptr, cmd_len);
483 DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw.CBWCDB, ":");
477 memset(&sc->cbw->CBWCDB, 0, sizeof(sc->cbw->CBWCDB));
478 memcpy(&sc->cbw->CBWCDB, cmd_ptr, cmd_len);
479 DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw->CBWCDB, ":");
484
485 mtx_lock(&sc->mtx);
486 usbd_transfer_start(sc->xfer[sc->state]);
487
488 while (usbd_transfer_pending(sc->xfer[sc->state])) {
489 cv_wait(&sc->cv, &sc->mtx);
490 }
491 mtx_unlock(&sc->mtx);

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

549 cv_init(&sc->cv, "WBBB");
550
551 err = usbd_transfer_setup(udev, &iface_index, sc->xfer, bbb_config,
552 ST_MAX, sc, &sc->mtx);
553 if (err) {
554 bbb_detach(sc);
555 return (NULL);
556 }
480
481 mtx_lock(&sc->mtx);
482 usbd_transfer_start(sc->xfer[sc->state]);
483
484 while (usbd_transfer_pending(sc->xfer[sc->state])) {
485 cv_wait(&sc->cv, &sc->mtx);
486 }
487 mtx_unlock(&sc->mtx);

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

545 cv_init(&sc->cv, "WBBB");
546
547 err = usbd_transfer_setup(udev, &iface_index, sc->xfer, bbb_config,
548 ST_MAX, sc, &sc->mtx);
549 if (err) {
550 bbb_detach(sc);
551 return (NULL);
552 }
553 /* store pointer to DMA buffers */
554 sc->buffer = usbd_xfer_get_frame_buffer(
555 sc->xfer[ST_DATA_RD], 0);
556 sc->cbw = usbd_xfer_get_frame_buffer(
557 sc->xfer[ST_COMMAND], 0);
558 sc->csw = usbd_xfer_get_frame_buffer(
559 sc->xfer[ST_STATUS], 0);
560
557 return (sc);
558}
559
560static void
561bbb_detach(struct bbb_transfer *sc)
562{
563 usbd_transfer_unsetup(sc->xfer, ST_MAX);
564 mtx_destroy(&sc->mtx);

--- 280 unchanged lines hidden ---
561 return (sc);
562}
563
564static void
565bbb_detach(struct bbb_transfer *sc)
566{
567 usbd_transfer_unsetup(sc->xfer, ST_MAX);
568 mtx_destroy(&sc->mtx);

--- 280 unchanged lines hidden ---