aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/hal/include/adc.h5
-rw-r--r--os/hal/src/adc.c2
-rw-r--r--os/various/usb_msc.c133
-rw-r--r--os/various/usb_msc.h31
4 files changed, 126 insertions, 45 deletions
diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h
index 8bc013b38..b0d6d0938 100644
--- a/os/hal/include/adc.h
+++ b/os/hal/include/adc.h
@@ -124,9 +124,10 @@ typedef enum {
*/
#define _adc_wakeup_isr(adcp) { \
if ((adcp)->thread != NULL) { \
- Thread *tp = (adcp)->thread; \
- (adcp)->thread = NULL; \
+ Thread *tp; \
chSysLockFromIsr(); \
+ tp = (adcp)->thread; \
+ (adcp)->thread = NULL; \
tp->p_u.rdymsg = RDY_OK; \
chSchReadyI(tp); \
chSysUnlockFromIsr(); \
diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c
index 956c7837f..b70c46e1c 100644
--- a/os/hal/src/adc.c
+++ b/os/hal/src/adc.c
@@ -271,7 +271,7 @@ msg_t adcConvert(ADCDriver *adcp,
msg_t msg;
chSysLock();
- chDbgAssert(grpp->end_cb == NULL, "adcConvert(), #1", "has callback");
+ chDbgAssert(adcp->thread == NULL, "adcConvert(), #1", "already waiting");
adcStartConversionI(adcp, grpp, samples, depth);
(adcp)->thread = chThdSelf();
chSchGoSleepS(THD_STATE_SUSPENDED);
diff --git a/os/various/usb_msc.c b/os/various/usb_msc.c
index dddc3f178..19d5ba8d6 100644
--- a/os/various/usb_msc.c
+++ b/os/various/usb_msc.c
@@ -44,29 +44,56 @@
static const uint8_t zerobuf[4] = {0, 0, 0, 0};
/**
- * @brief MSC state machine current state.
+ * @brief Answer to the INQUIRY command.
*/
-static mscstate_t msc_state;
+static const uint8_t scsi_inquiry_data[] = {
+ 0x00, /* Direct Access Device. */
+ 0x80, /* RMB = 1: Removable Medium. */
+ 0x02, /* ISO, ECMA, ANSI = 2. */
+ 0x00, /* UFI response format. */
+
+ 36 - 4, /* Additional Length. */
+ 0x00,
+ 0x00,
+ 0x00,
+ /* Vendor Identification */
+ 'C', 'h', 'i', 'b', 'i', 'O', 'S', ' ',
+ /* Product Identification */
+ 'S', 'D', ' ', 'F', 'l', 'a', 's', 'h',
+ ' ', 'D', 'i', 's', 'k', ' ', ' ', ' ',
+ /* Product Revision Level */
+ '1', '.', '0', ' '
+};
/**
- * @brief Transfer lenght specified in the CBW.
+ * @brief Generic buffer.
*/
-static uint32_t cbw_length;
+uint8_t buf[16];
-/**
- * @brief Tag specified in the CBW.
- */
-static uint32_t cbw_tag;
+/*===========================================================================*/
+/* MMC interface code. */
+/*===========================================================================*/
-/**
- * @brief Transmitted lenght.
- */
-static uint32_t csw_sent;
+/*===========================================================================*/
+/* SCSI emulation code. */
+/*===========================================================================*/
+
+static uint8_t scsi_read_format_capacities(uint32_t *nblocks,
+ uint32_t *secsize) {
+
+ *nblocks = 1024;
+ *secsize = 512;
+ return 3; /* No Media.*/
+}
+
+/*===========================================================================*/
+/* Mass Storage Class related code. */
+/*===========================================================================*/
/**
- * @brief Status.
+ * @brief MSC state machine current state.
*/
-static uint8_t csw_status;
+static mscstate_t msc_state;
/**
* @brief Received CBW.
@@ -78,10 +105,6 @@ static msccbw_t CBW;
*/
static msccsw_t CSW;
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
/**
* @brief MSC state machine initialization.
*
@@ -101,30 +124,40 @@ static void msc_transmit(USBDriver *usbp, const uint8_t *p, size_t n) {
n = CBW.dCBWDataTransferLength;
CSW.dCSWDataResidue = CBW.dCBWDataTransferLength - (uint32_t)n;
chSysLockFromIsr();
- usbStartTransmitI(usbp, MSC_DATA_IN_EP, scsi_inquiry_data, n);
+ usbStartTransmitI(usbp, MSC_DATA_IN_EP, p, n);
+ chSysUnlockFromIsr();
+}
+
+static void msc_sendstatus(USBDriver *usbp) {
+
+ msc_state = MSC_SENDING_CSW;
+ chSysLockFromIsr();
+ usbStartTransmitI(usbp, MSC_DATA_IN_EP, (uint8_t *)&CSW, sizeof CSW);
chSysUnlockFromIsr();
}
-static bool_t msc_decode_in(USBDriver *usbp) {
+static bool_t msc_decode(USBDriver *usbp) {
uint32_t nblocks, secsize;
- size_t n;
- switch (u.CBW.CBWCB[0]) {
+ switch (CBW.CBWCB[0]) {
+ case SCSI_REQUEST_SENSE:
+ break;
case SCSI_INQUIRY:
- msc_transmit(usbp, &scsi_inquiry_data, sizeof scsi_inquiry_data);
+ msc_transmit(usbp, (uint8_t *)&scsi_inquiry_data,
+ sizeof scsi_inquiry_data);
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
break;
case SCSI_READ_FORMAT_CAPACITIES:
buf[8] = scsi_read_format_capacities(&nblocks, &secsize);
- buf[0] = u.buf[1] = u.buf[2] = 0;
+ buf[0] = buf[1] = buf[2] = 0;
buf[3] = 8;
- buf[4] = (tU8)(nblocks >> 24);
- buf[5] = (tU8)(nblocks >> 16);
- buf[6] = (tU8)(nblocks >> 8);
- buf[7] = (tU8)(nblocks >> 0);
- buf[9] = (tU8)(secsize >> 16);
- buf[10] = (tU8)(secsize >> 8);
- buf[11] = (tU8)(secsize >> 0);
+ buf[4] = (uint8_t)(nblocks >> 24);
+ buf[5] = (uint8_t)(nblocks >> 16);
+ buf[6] = (uint8_t)(nblocks >> 8);
+ buf[7] = (uint8_t)(nblocks >> 0);
+ buf[9] = (uint8_t)(secsize >> 16);
+ buf[10] = (uint8_t)(secsize >> 8);
+ buf[11] = (uint8_t)(secsize >> 0);
msc_transmit(usbp, buf, 12);
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
break;
@@ -134,11 +167,6 @@ static bool_t msc_decode_in(USBDriver *usbp) {
return FALSE;
}
-static bool_t msc_decode_out(USBDriver *usbp) {
-
- return FALSE;
-}
-
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -221,18 +249,32 @@ void mscDataReceived(USBDriver *usbp, usbep_t ep) {
switch (msc_state) {
case MSC_IDLE:
if ((n != sizeof(msccbw_t)) || (CBW.dCBWSignature != MSC_CBW_SIGNATURE))
- goto stallout; /* 6.6.1 */
+ goto stall_out; /* 6.6.1 */
+
+ /* Decoding SCSI command.*/
+ if (msc_decode(usbp)) {
+ if (CBW.dCBWDataTransferLength == 0) {
+ CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
+ CSW.dCSWDataResidue = 0;
+ msc_sendstatus(usbp);
+ return;
+ }
+ goto stall_both;
+ }
+
+ /* Commands with zero transfer length, 5.1.*/
+ if (CBW.dCBWDataTransferLength == 0) {
+ msc_sendstatus(usbp);
+ return;
+ }
+ /* Transfer direction.*/
if (CBW.bmCBWFlags & 0x80) {
/* IN, Device to Host.*/
- if (msc_decode_in(usbp))
- goto stallout;
msc_state = MSC_DATA_IN;
}
else {
/* OUT, Host to Device.*/
- if (msc_decode_out(usbp))
- goto stallout;
msc_state = MSC_DATA_OUT;
}
break;
@@ -242,9 +284,16 @@ void mscDataReceived(USBDriver *usbp, usbep_t ep) {
;
}
return;
-stallout:
+stall_out:
+ msc_state = MSC_ERROR;
+ chSysLockFromIsr();
+ usbStallReceiveI(usbp, ep);
+ chSysUnlockFromIsr();
+ return;
+stall_both:
msc_state = MSC_ERROR;
chSysLockFromIsr();
+ usbStallTransmitI(usbp, ep);
usbStallReceiveI(usbp, ep);
chSysUnlockFromIsr();
return;
diff --git a/os/various/usb_msc.h b/os/various/usb_msc.h
index 952903933..d62bb001d 100644
--- a/os/various/usb_msc.h
+++ b/os/various/usb_msc.h
@@ -42,6 +42,37 @@
#define MSC_CSW_STATUS_FAILED 1
#define MSC_CSW_STATUS_PHASE_ERROR 2
+
+#define SCSI_FORMAT_UNIT 0x04
+#define SCSI_INQUIRY 0x12
+#define SCSI_MODE_SELECT6 0x15
+#define SCSI_MODE_SELECT10 0x55
+#define SCSI_MODE_SENSE6 0x1A
+#define SCSI_MODE_SENSE10 0x5A
+#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E
+#define SCSI_READ6 0x08
+#define SCSI_READ10 0x28
+#define SCSI_READ12 0xA8
+#define SCSI_READ16 0x88
+
+#define SCSI_READ_CAPACITY10 0x25
+#define SCSI_READ_CAPACITY16 0x9E
+
+#define SCSI_REQUEST_SENSE 0x03
+#define SCSI_START_STOP_UNIT 0x1B
+#define SCSI_TEST_UNIT_READY 0x00
+#define SCSI_WRITE6 0x0A
+#define SCSI_WRITE10 0x2A
+#define SCSI_WRITE12 0xAA
+#define SCSI_WRITE16 0x8A
+
+#define SCSI_VERIFY10 0x2F
+#define SCSI_VERIFY12 0xAF
+#define SCSI_VERIFY16 0x8F
+
+#define SCSI_SEND_DIAGNOSTIC 0x1D
+#define SCSI_READ_FORMAT_CAPACITIES 0x23
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/