Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Jun 2009 17:55:07 GMT
From:      Sylvestre Gallon <syl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 165325 for review
Message-ID:  <200906271755.n5RHt7Ca066933@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=165325

Change 165325 by syl@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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906271755.n5RHt7Ca066933>