diff options
Diffstat (limited to 'os')
-rw-r--r-- | os/hal/include/hal_usb_msd.h | 3 | ||||
-rw-r--r-- | os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c | 6 | ||||
-rw-r--r-- | os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h | 36 | ||||
-rw-r--r-- | os/hal/src/hal_usb_msd.c | 22 | ||||
-rw-r--r-- | os/various/lib_scsi.c | 78 | ||||
-rw-r--r-- | os/various/lib_scsi.h | 15 |
6 files changed, 131 insertions, 29 deletions
diff --git a/os/hal/include/hal_usb_msd.h b/os/hal/include/hal_usb_msd.h index fcc2cf2..0fe03e4 100644 --- a/os/hal/include/hal_usb_msd.h +++ b/os/hal/include/hal_usb_msd.h @@ -172,7 +172,8 @@ extern "C" { void msdObjectInit(USBMassStorageDriver *msdp); void msdStart(USBMassStorageDriver *msdp, USBDriver *usbp, BaseBlockDevice *blkdev, uint8_t *blkbuf, - const scsi_inquiry_response_t *scsi_inquiry_response); + const scsi_inquiry_response_t *scsi_inquiry_response, + const scsi_unit_serial_number_inquiry_response_t *serialInquiry); void msdStop(USBMassStorageDriver *msdp); bool msd_request_hook(USBDriver *usbp); #ifdef __cplusplus diff --git a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c index 98defed..126959f 100644 --- a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c +++ b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c @@ -359,6 +359,7 @@ void spi_lld_stop(SPIDriver *spip) } } +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) /** * @brief Asserts the slave select signal and prepares for transfers. * @@ -368,7 +369,7 @@ void spi_lld_stop(SPIDriver *spip) */ void spi_lld_select(SPIDriver *spip) { - palClearPad(spip->config->ssport, spip->config->sspad); + /* No implementation on Tiva.*/ } /** @@ -381,8 +382,9 @@ void spi_lld_select(SPIDriver *spip) */ void spi_lld_unselect(SPIDriver *spip) { - palSetPad(spip->config->ssport, spip->config->sspad); + /* No implementation on Tiva.*/ } +#endif /** * @brief Ignores data on the SPI bus. diff --git a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h index 64560eb..4dcf6db 100644 --- a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h +++ b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h @@ -165,6 +165,10 @@ #define TIVA_UDMA_REQUIRED #endif +#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD +#error "SPI_SELECT_MODE_LLD not supported by this driver" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -189,16 +193,34 @@ typedef struct { /** * @brief Operation complete callback or @p NULL. */ - spicallback_t end_cb; - /* End of the mandatory fields.*/ + spicallback_t end_cb; +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LINE) || defined(__DOXYGEN__) + /** + * @brief The chip select line. + */ + ioline_t ssline; +#endif +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PORT) || defined(__DOXYGEN__) + /** + * @brief The chip select port. + */ + ioportid_t ssport; /** - * @brief The chip select line port. + * @brief The chip select port mask. */ - ioportid_t ssport; + uint8fast_t ssmask; +#endif +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PAD) || defined(__DOXYGEN__) /** - * @brief The chip select line pad number. + * @brief The chip select port. */ - uint16_t sspad; + ioportid_t ssport; + /** + * @brief The chip select pad number. + */ + uint_fast8_t sspad; +#endif + /* End of the mandatory fields.*/ /** * @brief SSI CR0 initialization data. */ @@ -289,8 +311,10 @@ extern "C" { void spi_lld_init(void); void spi_lld_start(SPIDriver *spip); void spi_lld_stop(SPIDriver *spip); +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) void spi_lld_select(SPIDriver *spip); void spi_lld_unselect(SPIDriver *spip); +#endif void spi_lld_ignore(SPIDriver *spip, size_t n); void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf); diff --git a/os/hal/src/hal_usb_msd.c b/os/hal/src/hal_usb_msd.c index 6cc5386..564bad0 100644 --- a/os/hal/src/hal_usb_msd.c +++ b/os/hal/src/hal_usb_msd.c @@ -84,6 +84,19 @@ static const scsi_inquiry_response_t default_scsi_inquiry_response = { {'v',CH_KERNEL_MAJOR+'0','.',CH_KERNEL_MINOR+'0'} }; +/** + * @brief Hardcoded default SCSI unit serial number inquiry response structure. + */ +static const scsi_unit_serial_number_inquiry_response_t default_scsi_unit_serial_number_inquiry_response = +{ + 0x00, + 0x80, + 0x00, + 0x08, + "00000000" +}; + + /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ @@ -373,7 +386,8 @@ void msdStop(USBMassStorageDriver *msdp) { */ void msdStart(USBMassStorageDriver *msdp, USBDriver *usbp, BaseBlockDevice *blkdev, uint8_t *blkbuf, - const scsi_inquiry_response_t *inquiry) { + const scsi_inquiry_response_t *inquiry, + const scsi_unit_serial_number_inquiry_response_t *serialInquiry) { osalDbgCheck((msdp != NULL) && (usbp != NULL) && (blkdev != NULL) && (blkbuf != NULL)); @@ -393,6 +407,12 @@ void msdStart(USBMassStorageDriver *msdp, USBDriver *usbp, else { msdp->scsi_config.inquiry_response = inquiry; } + if (NULL == serialInquiry) { + msdp->scsi_config.unit_serial_number_inquiry_response = &default_scsi_unit_serial_number_inquiry_response; + } + else { + msdp->scsi_config.unit_serial_number_inquiry_response = serialInquiry; + } msdp->scsi_config.blkbuf = blkbuf; msdp->scsi_config.blkdev = blkdev; msdp->scsi_config.transport = &msdp->scsi_transport; diff --git a/os/various/lib_scsi.c b/os/various/lib_scsi.c index 55aeb7e..ea2adda 100644 --- a/os/various/lib_scsi.c +++ b/os/various/lib_scsi.c @@ -159,7 +159,6 @@ static bool cmd_ignored(SCSITarget *scsip, const uint8_t *cmd) { (void)scsip; (void)cmd; - set_sense_ok(scsip); return SCSI_SUCCESS; } @@ -175,7 +174,12 @@ static bool cmd_ignored(SCSITarget *scsip, const uint8_t *cmd) { */ static bool inquiry(SCSITarget *scsip, const uint8_t *cmd) { - if ((cmd[1] & 0b11) || cmd[2] != 0) { + if ((cmd[1] & 0b1) && cmd[2] == 0x80) { + /* Unit serial number page */ + return transmit_data(scsip, (const uint8_t *)scsip->config->unit_serial_number_inquiry_response, + sizeof(scsi_unit_serial_number_inquiry_response_t)); + } + else if ((cmd[1] & 0b11) || cmd[2] != 0) { set_sense(scsip, SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_ASENSE_INVALID_FIELD_IN_CDB, SCSI_ASENSEQ_NO_QUALIFIER); @@ -199,10 +203,7 @@ static bool inquiry(SCSITarget *scsip, const uint8_t *cmd) { */ static bool request_sense(SCSITarget *scsip, const uint8_t *cmd) { - uint32_t tmp; - memcpy(&tmp, &cmd[1], 3); - - if ((tmp != 0) || (cmd[4] != sizeof(scsi_sense_response_t))) { + if (((cmd[1] & 0x01) != 0) || (cmd[4] != sizeof(scsi_sense_response_t))) { set_sense(scsip, SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_ASENSE_INVALID_FIELD_IN_CDB, SCSI_ASENSEQ_NO_QUALIFIER); @@ -378,6 +379,30 @@ static bool data_read_write10(SCSITarget *scsip, const uint8_t *cmd) { } return SCSI_SUCCESS; } + +/** + * @brief SCSI test unit ready command handler + * @details If block device is inserted, sets sense data in 'all OK' condition + * and returns success status. + * If block device is not inserted, sets sense data to 'Medium not present' considion, + * and returns check condition status. + */ +static bool test_unit_ready(SCSITarget *scsip, const uint8_t *cmd) { + (void)cmd; + + if (blkIsInserted(scsip->config->blkdev)) { + return SCSI_SUCCESS; + } + else { + warnprintf("SCSI Medium is not inserted.\r\n"); + set_sense(scsip, SCSI_SENSE_KEY_NOT_READY, + SCSI_ASENSE_MEDIUM_NOT_PRESENT, + SCSI_ASENSEQ_NO_QUALIFIER); + return SCSI_FAILED; + } + +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -398,54 +423,69 @@ static bool data_read_write10(SCSITarget *scsip, const uint8_t *cmd) { */ bool scsiExecCmd(SCSITarget *scsip, const uint8_t *cmd) { - /* status will be overwritten later in case of error */ - set_sense_ok(scsip); + bool ret = SCSI_SUCCESS; switch (cmd[0]) { case SCSI_CMD_INQUIRY: dbgprintf("SCSI_CMD_INQUIRY\r\n"); - return inquiry(scsip, cmd); + ret = inquiry(scsip, cmd); + break; case SCSI_CMD_REQUEST_SENSE: dbgprintf("SCSI_CMD_REQUEST_SENSE\r\n"); - return request_sense(scsip, cmd); + ret = request_sense(scsip, cmd); + break; case SCSI_CMD_READ_CAPACITY_10: dbgprintf("SCSI_CMD_READ_CAPACITY_10\r\n"); - return read_capacity10(scsip, cmd); + ret = read_capacity10(scsip, cmd); + break; case SCSI_CMD_READ_10: dbgprintf("SCSI_CMD_READ_10\r\n"); - return data_read_write10(scsip, cmd); + ret = data_read_write10(scsip, cmd); + break; case SCSI_CMD_WRITE_10: dbgprintf("SCSI_CMD_WRITE_10\r\n"); - return data_read_write10(scsip, cmd); + ret = data_read_write10(scsip, cmd); + break; case SCSI_CMD_TEST_UNIT_READY: dbgprintf("SCSI_CMD_TEST_UNIT_READY\r\n"); - return cmd_ignored(scsip, cmd); + ret = test_unit_ready(scsip, cmd); + break; case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: dbgprintf("SCSI_CMD_ALLOW_MEDIUM_REMOVAL\r\n"); - return cmd_ignored(scsip, cmd); + ret = cmd_ignored(scsip, cmd); + break; case SCSI_CMD_MODE_SENSE_6: dbgprintf("SCSI_CMD_MODE_SENSE_6\r\n"); - return mode_sense6(scsip, cmd); + ret = mode_sense6(scsip, cmd); + break; case SCSI_CMD_READ_FORMAT_CAPACITIES: dbgprintf("SCSI_CMD_READ_FORMAT_CAPACITIES\r\n"); - return read_format_capacities(scsip, cmd); + ret = read_format_capacities(scsip, cmd); + break; case SCSI_CMD_VERIFY_10: dbgprintf("SCSI_CMD_VERIFY_10\r\n"); - return cmd_ignored(scsip, cmd); + ret = cmd_ignored(scsip, cmd); + break; default: warnprintf("SCSI unhandled command: %X\r\n", cmd[0]); - return cmd_unhandled(scsip, cmd); + ret = cmd_unhandled(scsip, cmd); + break; } + + if (ret == SCSI_SUCCESS) + set_sense_ok(scsip); + + return ret; } /** diff --git a/os/various/lib_scsi.h b/os/various/lib_scsi.h index 97badb0..8384ae3 100644 --- a/os/various/lib_scsi.h +++ b/os/various/lib_scsi.h @@ -133,6 +133,17 @@ typedef struct PACKED_VAR { } scsi_inquiry_response_t; /** + * @brief Represents SCSI unit serial number inquiry response structure. + * @details See SCSI specification. + */ +typedef struct PACKED_VAR { + uint8_t peripheral; + uint8_t page_code; + uint8_t reserved; + uint8_t page_length; + uint8_t serianNumber[8]; +} scsi_unit_serial_number_inquiry_response_t; +/** * @brief Represents SCSI mode sense (6) request structure. * @details See SCSI specification. */ @@ -225,6 +236,10 @@ typedef struct { * @brief Pointer to SCSI inquiry response object. */ const scsi_inquiry_response_t *inquiry_response; + /** + * @brief Pointer to SCSI unit serial number inquiry response object. + */ + const scsi_unit_serial_number_inquiry_response_t *unit_serial_number_inquiry_response; } SCSITargetConfig; /** |