PERFORCE change 165325 for review
Sylvestre Gallon
syl at FreeBSD.org
Sat Jun 27 17:55:09 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=165325
Change 165325 by syl at syl_atuin on 2009/06/27 17:54:57
Implement a test that dump the 512 first byte of a memory stick. This
code is a revamp of Hans Petter Selasky libusb20 memory stick tester.
Affected files ...
.. //depot/projects/soc2009/syl_usb/libusb-tests/transfers/test3/test3.c#3 edit
Differences ...
==== //depot/projects/soc2009/syl_usb/libusb-tests/transfers/test3/test3.c#3 (text+ko) ====
@@ -1,3 +1,4 @@
+#include <dev/usb/usb_endian.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
@@ -6,9 +7,143 @@
#define PID_TEST 0x8300
#define VID_TEST 0x05ac
-libusb_context *ctx;
+static const uint8_t mode_sense_6[0x6] = {0x1a, 0, 0x3f, 0, 0x0c};
+static const uint8_t mode_sense_10[0xC] = {0x5A, 0, 0x05, 0, 0, 0, 0, 0, 0, 0x28};
+static const uint8_t read_capacity[0xA] = {0x25,};
+static const uint8_t request_sense[0xC] = {0x03, 0, 0, 0, 0x12};
+ const uint8_t test_unit_ready[0x6] = {0};
+static libusb_context *ctx;
+libusb_device_handle *devh;
+#define BLOCK_SIZE 512
+static uint8_t buffer[1024 * BLOCK_SIZE];
+static uint32_t cursig = 0;
+/* Command Block Wrapper */
+typedef struct {
+ uDWord dCBWSignature;
+#define CBWSIGNATURE 0x43425355
+ uDWord dCBWTag;
+ uDWord dCBWDataTransferLength;
+ uByte bCBWFlags;
+#define CBWFLAGS_OUT 0x00
+#define CBWFLAGS_IN 0x80
+ uByte bCBWLUN;
+ uByte bCDBLength;
+#define CBWCDBLENGTH 16
+ uByte CBWCDB[CBWCDBLENGTH];
+} umass_bbb_cbw_t;
+
+#define UMASS_BBB_CBW_SIZE 31
+typedef struct {
+ uDWord dCSWSignature;
+#define CSWSIGNATURE 0x53425355
+#define CSWSIGNATURE_IMAGINATION_DBX1 0x43425355
+#define CSWSIGNATURE_OLYMPUS_C1 0x55425355
+ uDWord dCSWTag;
+ uDWord dCSWDataResidue;
+ uByte bCSWStatus;
+#define CSWSTATUS_GOOD 0x0
+#define CSWSTATUS_FAILED 0x1
+#define CSWSTATUS_PHASE 0x2
+} umass_bbb_csw_t;
+
+#define UMASS_BBB_CSW_SIZE 13
+
+#define EP_IN 0x81
+#define EP_OUT 0x2
+
+
+void
+do_io(unsigned char ep, void *buff, uint32_t len, uint32_t timeout)
+{
+ int transferred = 0;
+
+ libusb_bulk_transfer(devh, ep, buff, len, &transferred, timeout);
+ while(!transferred);
+}
+
+void
+do_msc_req(const uint8_t *pcmd, uint8_t cmdlen, uint32_t datalen)
+{
+ umass_bbb_cbw_t cbw;
+ umass_bbb_csw_t csw;
+
+ bzero(&cbw, sizeof(cbw));
+
+ USETDW(cbw.dCBWSignature, CBWSIGNATURE);
+ USETDW(cbw.dCBWTag, cursig);
+ cursig++;
+ USETDW(cbw.dCBWDataTransferLength, datalen);
+ cbw.bCBWFlags = CBWFLAGS_IN;
+ cbw.bCBWLUN = 0;
+ cbw.bCDBLength = cmdlen;
+ bcopy(pcmd, cbw.CBWCDB, cmdlen);
+
+ do_io(EP_OUT, &cbw, sizeof(cbw), 10000);
+ if (datalen != 0) {
+ do_io(EP_IN, buffer, datalen, 10000);
+ }
+ do_io(EP_IN, &csw, sizeof(csw), 10000);
+ if (csw.bCSWStatus != 0) {
+ printf("command (0x%02x) cursig=0x%08x failed\n", pcmd[0], cursig);
+ } else {
+ printf("command (0x%02x) cursig=0x%08x success\n", pcmd[0], cursig);
+ }
+}
+
+void
+do_read(uint32_t lba, uint32_t len)
+{
+ static uint8_t cmd[10];
+
+ cmd[0] = 0x28;
+ len /= 512;
+
+ cmd[2] = lba >> 24;
+ cmd[3] = lba >> 16;
+ cmd[4] = lba >> 8;
+ cmd[5] = lba >> 0;
+
+ cmd[7] = len >> 8;
+ cmd[8] = len;
+ do_msc_req(cmd, 10, len * 512);
+}
int main(int ac, char *av[])
{
+ volatile int transferred;
+
+ printf("this test dump the 512 first byte of a memory stick\n");
+ if (libusb_init(&ctx) != 0) {
+ fprintf(stderr, "libusb_init_failed\n");
+ return (EXIT_FAILURE);
+ }
+
+ transferred = 0;
+ if ((devh = libusb_open_device_with_vid_pid(ctx, VID_TEST, PID_TEST)) != NULL) {
+ libusb_detach_kernel_driver(devh, 1);
+ libusb_clear_halt(devh, EP_IN);
+ libusb_clear_halt(devh, EP_OUT);
+
+ do_msc_req(mode_sense_6, sizeof(mode_sense_6),0xc);
+ do_msc_req(request_sense, sizeof(request_sense), 0x12);
+ do_msc_req(read_capacity, sizeof(read_capacity), 0x8);
+ do_msc_req(request_sense, sizeof(request_sense), 0x12);
+ do_msc_req(read_capacity, sizeof(read_capacity), 0x8);
+ do_msc_req(request_sense, sizeof(request_sense), 0x12);
+ do_msc_req(test_unit_ready, sizeof(test_unit_ready), 0xd);
+ do_msc_req(test_unit_ready, sizeof(test_unit_ready), 0xd);
+ do_msc_req(request_sense, sizeof(request_sense), 0x12);
+ do_msc_req(test_unit_ready, sizeof(test_unit_ready), 0xd);
+ do_msc_req(request_sense, sizeof(request_sense), 0x12);
+ do_msc_req(test_unit_ready, sizeof(test_unit_ready), 0xd);
+ do_msc_req(test_unit_ready, sizeof(test_unit_ready), 0xd);
+ do_msc_req(test_unit_ready, sizeof(test_unit_ready), 0xd);
+ do_msc_req(request_sense, sizeof(request_sense), 0x12);
+ do_msc_req(test_unit_ready, sizeof(test_unit_ready), 0xd);
+ do_msc_req(read_capacity, sizeof(read_capacity), 0x8);
+
+ do_read(0, BLOCK_SIZE);
+ }
+
return (EXIT_SUCCESS);
}
More information about the p4-projects
mailing list