Fixed bug 3205410.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2813 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
f27e4f46fe
commit
a849378300
|
@ -124,9 +124,10 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
#define _adc_wakeup_isr(adcp) { \
|
#define _adc_wakeup_isr(adcp) { \
|
||||||
if ((adcp)->thread != NULL) { \
|
if ((adcp)->thread != NULL) { \
|
||||||
Thread *tp = (adcp)->thread; \
|
Thread *tp; \
|
||||||
(adcp)->thread = NULL; \
|
|
||||||
chSysLockFromIsr(); \
|
chSysLockFromIsr(); \
|
||||||
|
tp = (adcp)->thread; \
|
||||||
|
(adcp)->thread = NULL; \
|
||||||
tp->p_u.rdymsg = RDY_OK; \
|
tp->p_u.rdymsg = RDY_OK; \
|
||||||
chSchReadyI(tp); \
|
chSchReadyI(tp); \
|
||||||
chSysUnlockFromIsr(); \
|
chSysUnlockFromIsr(); \
|
||||||
|
|
|
@ -271,7 +271,7 @@ msg_t adcConvert(ADCDriver *adcp,
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chDbgAssert(grpp->end_cb == NULL, "adcConvert(), #1", "has callback");
|
chDbgAssert(adcp->thread == NULL, "adcConvert(), #1", "already waiting");
|
||||||
adcStartConversionI(adcp, grpp, samples, depth);
|
adcStartConversionI(adcp, grpp, samples, depth);
|
||||||
(adcp)->thread = chThdSelf();
|
(adcp)->thread = chThdSelf();
|
||||||
chSchGoSleepS(THD_STATE_SUSPENDED);
|
chSchGoSleepS(THD_STATE_SUSPENDED);
|
||||||
|
|
|
@ -43,31 +43,58 @@
|
||||||
*/
|
*/
|
||||||
static const uint8_t zerobuf[4] = {0, 0, 0, 0};
|
static const uint8_t zerobuf[4] = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Answer to the INQUIRY command.
|
||||||
|
*/
|
||||||
|
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 Generic buffer.
|
||||||
|
*/
|
||||||
|
uint8_t buf[16];
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* MMC interface code. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* 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 MSC state machine current state.
|
* @brief MSC state machine current state.
|
||||||
*/
|
*/
|
||||||
static mscstate_t msc_state;
|
static mscstate_t msc_state;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Transfer lenght specified in the CBW.
|
|
||||||
*/
|
|
||||||
static uint32_t cbw_length;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Tag specified in the CBW.
|
|
||||||
*/
|
|
||||||
static uint32_t cbw_tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Transmitted lenght.
|
|
||||||
*/
|
|
||||||
static uint32_t csw_sent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Status.
|
|
||||||
*/
|
|
||||||
static uint8_t csw_status;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Received CBW.
|
* @brief Received CBW.
|
||||||
*/
|
*/
|
||||||
|
@ -78,10 +105,6 @@ static msccbw_t CBW;
|
||||||
*/
|
*/
|
||||||
static msccsw_t CSW;
|
static msccsw_t CSW;
|
||||||
|
|
||||||
/*===========================================================================*/
|
|
||||||
/* Driver local functions. */
|
|
||||||
/*===========================================================================*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MSC state machine initialization.
|
* @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;
|
n = CBW.dCBWDataTransferLength;
|
||||||
CSW.dCSWDataResidue = CBW.dCBWDataTransferLength - (uint32_t)n;
|
CSW.dCSWDataResidue = CBW.dCBWDataTransferLength - (uint32_t)n;
|
||||||
chSysLockFromIsr();
|
chSysLockFromIsr();
|
||||||
usbStartTransmitI(usbp, MSC_DATA_IN_EP, scsi_inquiry_data, n);
|
usbStartTransmitI(usbp, MSC_DATA_IN_EP, p, n);
|
||||||
chSysUnlockFromIsr();
|
chSysUnlockFromIsr();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool_t msc_decode_in(USBDriver *usbp) {
|
static void msc_sendstatus(USBDriver *usbp) {
|
||||||
uint32_t nblocks, secsize;
|
|
||||||
size_t n;
|
|
||||||
|
|
||||||
switch (u.CBW.CBWCB[0]) {
|
msc_state = MSC_SENDING_CSW;
|
||||||
|
chSysLockFromIsr();
|
||||||
|
usbStartTransmitI(usbp, MSC_DATA_IN_EP, (uint8_t *)&CSW, sizeof CSW);
|
||||||
|
chSysUnlockFromIsr();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t msc_decode(USBDriver *usbp) {
|
||||||
|
uint32_t nblocks, secsize;
|
||||||
|
|
||||||
|
switch (CBW.CBWCB[0]) {
|
||||||
|
case SCSI_REQUEST_SENSE:
|
||||||
|
break;
|
||||||
case SCSI_INQUIRY:
|
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;
|
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
|
||||||
break;
|
break;
|
||||||
case SCSI_READ_FORMAT_CAPACITIES:
|
case SCSI_READ_FORMAT_CAPACITIES:
|
||||||
buf[8] = scsi_read_format_capacities(&nblocks, &secsize);
|
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[3] = 8;
|
||||||
buf[4] = (tU8)(nblocks >> 24);
|
buf[4] = (uint8_t)(nblocks >> 24);
|
||||||
buf[5] = (tU8)(nblocks >> 16);
|
buf[5] = (uint8_t)(nblocks >> 16);
|
||||||
buf[6] = (tU8)(nblocks >> 8);
|
buf[6] = (uint8_t)(nblocks >> 8);
|
||||||
buf[7] = (tU8)(nblocks >> 0);
|
buf[7] = (uint8_t)(nblocks >> 0);
|
||||||
buf[9] = (tU8)(secsize >> 16);
|
buf[9] = (uint8_t)(secsize >> 16);
|
||||||
buf[10] = (tU8)(secsize >> 8);
|
buf[10] = (uint8_t)(secsize >> 8);
|
||||||
buf[11] = (tU8)(secsize >> 0);
|
buf[11] = (uint8_t)(secsize >> 0);
|
||||||
msc_transmit(usbp, buf, 12);
|
msc_transmit(usbp, buf, 12);
|
||||||
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
|
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
|
||||||
break;
|
break;
|
||||||
|
@ -134,11 +167,6 @@ static bool_t msc_decode_in(USBDriver *usbp) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool_t msc_decode_out(USBDriver *usbp) {
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver exported functions. */
|
/* Driver exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -221,18 +249,32 @@ void mscDataReceived(USBDriver *usbp, usbep_t ep) {
|
||||||
switch (msc_state) {
|
switch (msc_state) {
|
||||||
case MSC_IDLE:
|
case MSC_IDLE:
|
||||||
if ((n != sizeof(msccbw_t)) || (CBW.dCBWSignature != MSC_CBW_SIGNATURE))
|
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) {
|
if (CBW.bmCBWFlags & 0x80) {
|
||||||
/* IN, Device to Host.*/
|
/* IN, Device to Host.*/
|
||||||
if (msc_decode_in(usbp))
|
|
||||||
goto stallout;
|
|
||||||
msc_state = MSC_DATA_IN;
|
msc_state = MSC_DATA_IN;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* OUT, Host to Device.*/
|
/* OUT, Host to Device.*/
|
||||||
if (msc_decode_out(usbp))
|
|
||||||
goto stallout;
|
|
||||||
msc_state = MSC_DATA_OUT;
|
msc_state = MSC_DATA_OUT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -242,10 +284,17 @@ void mscDataReceived(USBDriver *usbp, usbep_t ep) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
stallout:
|
stall_out:
|
||||||
msc_state = MSC_ERROR;
|
msc_state = MSC_ERROR;
|
||||||
chSysLockFromIsr();
|
chSysLockFromIsr();
|
||||||
usbStallReceiveI(usbp, ep);
|
usbStallReceiveI(usbp, ep);
|
||||||
chSysUnlockFromIsr();
|
chSysUnlockFromIsr();
|
||||||
return;
|
return;
|
||||||
|
stall_both:
|
||||||
|
msc_state = MSC_ERROR;
|
||||||
|
chSysLockFromIsr();
|
||||||
|
usbStallTransmitI(usbp, ep);
|
||||||
|
usbStallReceiveI(usbp, ep);
|
||||||
|
chSysUnlockFromIsr();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,37 @@
|
||||||
#define MSC_CSW_STATUS_FAILED 1
|
#define MSC_CSW_STATUS_FAILED 1
|
||||||
#define MSC_CSW_STATUS_PHASE_ERROR 2
|
#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. */
|
/* Driver pre-compile time settings. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
Loading…
Reference in New Issue